1 //===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines classes for handling the YAML representation of wasm.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ObjectYAML/WasmYAML.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/Casting.h"
16 #include "llvm/Support/ErrorHandling.h"
17 #include "llvm/Support/YAMLTraits.h"
23 // Declared here rather than in the header to comply with:
24 // http://llvm.org/docs/CodingStandards.html#provide-a-virtual-method-anchor-for-classes-in-headers
25 Section::~Section() = default;
27 } // end namespace WasmYAML
31 void MappingTraits
<WasmYAML::FileHeader
>::mapping(
32 IO
&IO
, WasmYAML::FileHeader
&FileHdr
) {
33 IO
.mapRequired("Version", FileHdr
.Version
);
36 void MappingTraits
<WasmYAML::Object
>::mapping(IO
&IO
,
37 WasmYAML::Object
&Object
) {
38 IO
.setContext(&Object
);
39 IO
.mapTag("!WASM", true);
40 IO
.mapRequired("FileHeader", Object
.Header
);
41 IO
.mapOptional("Sections", Object
.Sections
);
42 IO
.setContext(nullptr);
45 static void commonSectionMapping(IO
&IO
, WasmYAML::Section
&Section
) {
46 IO
.mapRequired("Type", Section
.Type
);
47 IO
.mapOptional("Relocations", Section
.Relocations
);
50 static void sectionMapping(IO
&IO
, WasmYAML::DylinkSection
&Section
) {
51 commonSectionMapping(IO
, Section
);
52 IO
.mapRequired("Name", Section
.Name
);
53 IO
.mapRequired("MemorySize", Section
.MemorySize
);
54 IO
.mapRequired("MemoryAlignment", Section
.MemoryAlignment
);
55 IO
.mapRequired("TableSize", Section
.TableSize
);
56 IO
.mapRequired("TableAlignment", Section
.TableAlignment
);
57 IO
.mapRequired("Needed", Section
.Needed
);
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
);
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
);
76 static void sectionMapping(IO
&IO
, WasmYAML::ProducersSection
&Section
) {
77 commonSectionMapping(IO
, Section
);
78 IO
.mapRequired("Name", Section
.Name
);
79 IO
.mapOptional("Languages", Section
.Languages
);
80 IO
.mapOptional("Tools", Section
.Tools
);
81 IO
.mapOptional("SDKs", Section
.SDKs
);
84 static void sectionMapping(IO
&IO
, WasmYAML::CustomSection
&Section
) {
85 commonSectionMapping(IO
, Section
);
86 IO
.mapRequired("Name", Section
.Name
);
87 IO
.mapRequired("Payload", Section
.Payload
);
90 static void sectionMapping(IO
&IO
, WasmYAML::TypeSection
&Section
) {
91 commonSectionMapping(IO
, Section
);
92 IO
.mapOptional("Signatures", Section
.Signatures
);
95 static void sectionMapping(IO
&IO
, WasmYAML::ImportSection
&Section
) {
96 commonSectionMapping(IO
, Section
);
97 IO
.mapOptional("Imports", Section
.Imports
);
100 static void sectionMapping(IO
&IO
, WasmYAML::FunctionSection
&Section
) {
101 commonSectionMapping(IO
, Section
);
102 IO
.mapOptional("FunctionTypes", Section
.FunctionTypes
);
105 static void sectionMapping(IO
&IO
, WasmYAML::TableSection
&Section
) {
106 commonSectionMapping(IO
, Section
);
107 IO
.mapOptional("Tables", Section
.Tables
);
110 static void sectionMapping(IO
&IO
, WasmYAML::MemorySection
&Section
) {
111 commonSectionMapping(IO
, Section
);
112 IO
.mapOptional("Memories", Section
.Memories
);
115 static void sectionMapping(IO
&IO
, WasmYAML::GlobalSection
&Section
) {
116 commonSectionMapping(IO
, Section
);
117 IO
.mapOptional("Globals", Section
.Globals
);
120 static void sectionMapping(IO
&IO
, WasmYAML::EventSection
&Section
) {
121 commonSectionMapping(IO
, Section
);
122 IO
.mapOptional("Events", Section
.Events
);
125 static void sectionMapping(IO
&IO
, WasmYAML::ExportSection
&Section
) {
126 commonSectionMapping(IO
, Section
);
127 IO
.mapOptional("Exports", Section
.Exports
);
130 static void sectionMapping(IO
&IO
, WasmYAML::StartSection
&Section
) {
131 commonSectionMapping(IO
, Section
);
132 IO
.mapOptional("StartFunction", Section
.StartFunction
);
135 static void sectionMapping(IO
&IO
, WasmYAML::ElemSection
&Section
) {
136 commonSectionMapping(IO
, Section
);
137 IO
.mapOptional("Segments", Section
.Segments
);
140 static void sectionMapping(IO
&IO
, WasmYAML::CodeSection
&Section
) {
141 commonSectionMapping(IO
, Section
);
142 IO
.mapRequired("Functions", Section
.Functions
);
145 static void sectionMapping(IO
&IO
, WasmYAML::DataSection
&Section
) {
146 commonSectionMapping(IO
, Section
);
147 IO
.mapRequired("Segments", Section
.Segments
);
150 void MappingTraits
<std::unique_ptr
<WasmYAML::Section
>>::mapping(
151 IO
&IO
, std::unique_ptr
<WasmYAML::Section
> &Section
) {
152 WasmYAML::SectionType SectionType
;
154 SectionType
= Section
->Type
;
156 IO
.mapRequired("Type", SectionType
);
158 switch (SectionType
) {
159 case wasm::WASM_SEC_CUSTOM
: {
160 StringRef SectionName
;
161 if (IO
.outputting()) {
162 auto CustomSection
= cast
<WasmYAML::CustomSection
>(Section
.get());
163 SectionName
= CustomSection
->Name
;
165 IO
.mapRequired("Name", SectionName
);
167 if (SectionName
== "dylink") {
168 if (!IO
.outputting())
169 Section
.reset(new WasmYAML::DylinkSection());
170 sectionMapping(IO
, *cast
<WasmYAML::DylinkSection
>(Section
.get()));
171 } else if (SectionName
== "linking") {
172 if (!IO
.outputting())
173 Section
.reset(new WasmYAML::LinkingSection());
174 sectionMapping(IO
, *cast
<WasmYAML::LinkingSection
>(Section
.get()));
175 } else if (SectionName
== "name") {
176 if (!IO
.outputting())
177 Section
.reset(new WasmYAML::NameSection());
178 sectionMapping(IO
, *cast
<WasmYAML::NameSection
>(Section
.get()));
179 } else if (SectionName
== "producers") {
180 if (!IO
.outputting())
181 Section
.reset(new WasmYAML::ProducersSection());
182 sectionMapping(IO
, *cast
<WasmYAML::ProducersSection
>(Section
.get()));
184 if (!IO
.outputting())
185 Section
.reset(new WasmYAML::CustomSection(SectionName
));
186 sectionMapping(IO
, *cast
<WasmYAML::CustomSection
>(Section
.get()));
190 case wasm::WASM_SEC_TYPE
:
191 if (!IO
.outputting())
192 Section
.reset(new WasmYAML::TypeSection());
193 sectionMapping(IO
, *cast
<WasmYAML::TypeSection
>(Section
.get()));
195 case wasm::WASM_SEC_IMPORT
:
196 if (!IO
.outputting())
197 Section
.reset(new WasmYAML::ImportSection());
198 sectionMapping(IO
, *cast
<WasmYAML::ImportSection
>(Section
.get()));
200 case wasm::WASM_SEC_FUNCTION
:
201 if (!IO
.outputting())
202 Section
.reset(new WasmYAML::FunctionSection());
203 sectionMapping(IO
, *cast
<WasmYAML::FunctionSection
>(Section
.get()));
205 case wasm::WASM_SEC_TABLE
:
206 if (!IO
.outputting())
207 Section
.reset(new WasmYAML::TableSection());
208 sectionMapping(IO
, *cast
<WasmYAML::TableSection
>(Section
.get()));
210 case wasm::WASM_SEC_MEMORY
:
211 if (!IO
.outputting())
212 Section
.reset(new WasmYAML::MemorySection());
213 sectionMapping(IO
, *cast
<WasmYAML::MemorySection
>(Section
.get()));
215 case wasm::WASM_SEC_GLOBAL
:
216 if (!IO
.outputting())
217 Section
.reset(new WasmYAML::GlobalSection());
218 sectionMapping(IO
, *cast
<WasmYAML::GlobalSection
>(Section
.get()));
220 case wasm::WASM_SEC_EVENT
:
221 if (!IO
.outputting())
222 Section
.reset(new WasmYAML::EventSection());
223 sectionMapping(IO
, *cast
<WasmYAML::EventSection
>(Section
.get()));
225 case wasm::WASM_SEC_EXPORT
:
226 if (!IO
.outputting())
227 Section
.reset(new WasmYAML::ExportSection());
228 sectionMapping(IO
, *cast
<WasmYAML::ExportSection
>(Section
.get()));
230 case wasm::WASM_SEC_START
:
231 if (!IO
.outputting())
232 Section
.reset(new WasmYAML::StartSection());
233 sectionMapping(IO
, *cast
<WasmYAML::StartSection
>(Section
.get()));
235 case wasm::WASM_SEC_ELEM
:
236 if (!IO
.outputting())
237 Section
.reset(new WasmYAML::ElemSection());
238 sectionMapping(IO
, *cast
<WasmYAML::ElemSection
>(Section
.get()));
240 case wasm::WASM_SEC_CODE
:
241 if (!IO
.outputting())
242 Section
.reset(new WasmYAML::CodeSection());
243 sectionMapping(IO
, *cast
<WasmYAML::CodeSection
>(Section
.get()));
245 case wasm::WASM_SEC_DATA
:
246 if (!IO
.outputting())
247 Section
.reset(new WasmYAML::DataSection());
248 sectionMapping(IO
, *cast
<WasmYAML::DataSection
>(Section
.get()));
251 llvm_unreachable("Unknown section type");
255 void ScalarEnumerationTraits
<WasmYAML::SectionType
>::enumeration(
256 IO
&IO
, WasmYAML::SectionType
&Type
) {
257 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X);
274 void MappingTraits
<WasmYAML::Signature
>::mapping(
275 IO
&IO
, WasmYAML::Signature
&Signature
) {
276 IO
.mapRequired("Index", Signature
.Index
);
277 IO
.mapRequired("ReturnType", Signature
.ReturnType
);
278 IO
.mapRequired("ParamTypes", Signature
.ParamTypes
);
281 void MappingTraits
<WasmYAML::Table
>::mapping(IO
&IO
, WasmYAML::Table
&Table
) {
282 IO
.mapRequired("ElemType", Table
.ElemType
);
283 IO
.mapRequired("Limits", Table
.TableLimits
);
286 void MappingTraits
<WasmYAML::Function
>::mapping(IO
&IO
,
287 WasmYAML::Function
&Function
) {
288 IO
.mapRequired("Index", Function
.Index
);
289 IO
.mapRequired("Locals", Function
.Locals
);
290 IO
.mapRequired("Body", Function
.Body
);
293 void MappingTraits
<WasmYAML::Relocation
>::mapping(
294 IO
&IO
, WasmYAML::Relocation
&Relocation
) {
295 IO
.mapRequired("Type", Relocation
.Type
);
296 IO
.mapRequired("Index", Relocation
.Index
);
297 IO
.mapRequired("Offset", Relocation
.Offset
);
298 IO
.mapOptional("Addend", Relocation
.Addend
, 0);
301 void MappingTraits
<WasmYAML::NameEntry
>::mapping(
302 IO
&IO
, WasmYAML::NameEntry
&NameEntry
) {
303 IO
.mapRequired("Index", NameEntry
.Index
);
304 IO
.mapRequired("Name", NameEntry
.Name
);
307 void MappingTraits
<WasmYAML::ProducerEntry
>::mapping(
308 IO
&IO
, WasmYAML::ProducerEntry
&ProducerEntry
) {
309 IO
.mapRequired("Name", ProducerEntry
.Name
);
310 IO
.mapRequired("Version", ProducerEntry
.Version
);
313 void MappingTraits
<WasmYAML::SegmentInfo
>::mapping(
314 IO
&IO
, WasmYAML::SegmentInfo
&SegmentInfo
) {
315 IO
.mapRequired("Index", SegmentInfo
.Index
);
316 IO
.mapRequired("Name", SegmentInfo
.Name
);
317 IO
.mapRequired("Alignment", SegmentInfo
.Alignment
);
318 IO
.mapRequired("Flags", SegmentInfo
.Flags
);
321 void MappingTraits
<WasmYAML::LocalDecl
>::mapping(
322 IO
&IO
, WasmYAML::LocalDecl
&LocalDecl
) {
323 IO
.mapRequired("Type", LocalDecl
.Type
);
324 IO
.mapRequired("Count", LocalDecl
.Count
);
327 void MappingTraits
<WasmYAML::Limits
>::mapping(IO
&IO
,
328 WasmYAML::Limits
&Limits
) {
329 if (!IO
.outputting() || Limits
.Flags
)
330 IO
.mapOptional("Flags", Limits
.Flags
);
331 IO
.mapRequired("Initial", Limits
.Initial
);
332 if (!IO
.outputting() || Limits
.Flags
& wasm::WASM_LIMITS_FLAG_HAS_MAX
)
333 IO
.mapOptional("Maximum", Limits
.Maximum
);
336 void MappingTraits
<WasmYAML::ElemSegment
>::mapping(
337 IO
&IO
, WasmYAML::ElemSegment
&Segment
) {
338 IO
.mapRequired("Offset", Segment
.Offset
);
339 IO
.mapRequired("Functions", Segment
.Functions
);
342 void MappingTraits
<WasmYAML::Import
>::mapping(IO
&IO
,
343 WasmYAML::Import
&Import
) {
344 IO
.mapRequired("Module", Import
.Module
);
345 IO
.mapRequired("Field", Import
.Field
);
346 IO
.mapRequired("Kind", Import
.Kind
);
347 if (Import
.Kind
== wasm::WASM_EXTERNAL_FUNCTION
) {
348 IO
.mapRequired("SigIndex", Import
.SigIndex
);
349 } else if (Import
.Kind
== wasm::WASM_EXTERNAL_GLOBAL
) {
350 IO
.mapRequired("GlobalType", Import
.GlobalImport
.Type
);
351 IO
.mapRequired("GlobalMutable", Import
.GlobalImport
.Mutable
);
352 } else if (Import
.Kind
== wasm::WASM_EXTERNAL_EVENT
) {
353 IO
.mapRequired("EventAttribute", Import
.EventImport
.Attribute
);
354 IO
.mapRequired("EventSigIndex", Import
.EventImport
.SigIndex
);
355 } else if (Import
.Kind
== wasm::WASM_EXTERNAL_TABLE
) {
356 IO
.mapRequired("Table", Import
.TableImport
);
357 } else if (Import
.Kind
== wasm::WASM_EXTERNAL_MEMORY
) {
358 IO
.mapRequired("Memory", Import
.Memory
);
360 llvm_unreachable("unhandled import type");
364 void MappingTraits
<WasmYAML::Export
>::mapping(IO
&IO
,
365 WasmYAML::Export
&Export
) {
366 IO
.mapRequired("Name", Export
.Name
);
367 IO
.mapRequired("Kind", Export
.Kind
);
368 IO
.mapRequired("Index", Export
.Index
);
371 void MappingTraits
<WasmYAML::Global
>::mapping(IO
&IO
,
372 WasmYAML::Global
&Global
) {
373 IO
.mapRequired("Index", Global
.Index
);
374 IO
.mapRequired("Type", Global
.Type
);
375 IO
.mapRequired("Mutable", Global
.Mutable
);
376 IO
.mapRequired("InitExpr", Global
.InitExpr
);
379 void MappingTraits
<wasm::WasmInitExpr
>::mapping(IO
&IO
,
380 wasm::WasmInitExpr
&Expr
) {
381 WasmYAML::Opcode Op
= Expr
.Opcode
;
382 IO
.mapRequired("Opcode", Op
);
384 switch (Expr
.Opcode
) {
385 case wasm::WASM_OPCODE_I32_CONST
:
386 IO
.mapRequired("Value", Expr
.Value
.Int32
);
388 case wasm::WASM_OPCODE_I64_CONST
:
389 IO
.mapRequired("Value", Expr
.Value
.Int64
);
391 case wasm::WASM_OPCODE_F32_CONST
:
392 IO
.mapRequired("Value", Expr
.Value
.Float32
);
394 case wasm::WASM_OPCODE_F64_CONST
:
395 IO
.mapRequired("Value", Expr
.Value
.Float64
);
397 case wasm::WASM_OPCODE_GLOBAL_GET
:
398 IO
.mapRequired("Index", Expr
.Value
.Global
);
403 void MappingTraits
<WasmYAML::DataSegment
>::mapping(
404 IO
&IO
, WasmYAML::DataSegment
&Segment
) {
405 IO
.mapOptional("SectionOffset", Segment
.SectionOffset
);
406 IO
.mapRequired("MemoryIndex", Segment
.MemoryIndex
);
407 IO
.mapRequired("Offset", Segment
.Offset
);
408 IO
.mapRequired("Content", Segment
.Content
);
411 void MappingTraits
<WasmYAML::InitFunction
>::mapping(
412 IO
&IO
, WasmYAML::InitFunction
&Init
) {
413 IO
.mapRequired("Priority", Init
.Priority
);
414 IO
.mapRequired("Symbol", Init
.Symbol
);
417 void ScalarEnumerationTraits
<WasmYAML::ComdatKind
>::enumeration(
418 IO
&IO
, WasmYAML::ComdatKind
&Kind
) {
419 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X);
425 void MappingTraits
<WasmYAML::ComdatEntry
>::mapping(
426 IO
&IO
, WasmYAML::ComdatEntry
&ComdatEntry
) {
427 IO
.mapRequired("Kind", ComdatEntry
.Kind
);
428 IO
.mapRequired("Index", ComdatEntry
.Index
);
431 void MappingTraits
<WasmYAML::Comdat
>::mapping(IO
&IO
,
432 WasmYAML::Comdat
&Comdat
) {
433 IO
.mapRequired("Name", Comdat
.Name
);
434 IO
.mapRequired("Entries", Comdat
.Entries
);
437 void MappingTraits
<WasmYAML::SymbolInfo
>::mapping(IO
&IO
,
438 WasmYAML::SymbolInfo
&Info
) {
439 IO
.mapRequired("Index", Info
.Index
);
440 IO
.mapRequired("Kind", Info
.Kind
);
441 IO
.mapRequired("Name", Info
.Name
);
442 IO
.mapRequired("Flags", Info
.Flags
);
443 if (Info
.Kind
== wasm::WASM_SYMBOL_TYPE_FUNCTION
) {
444 IO
.mapRequired("Function", Info
.ElementIndex
);
445 } else if (Info
.Kind
== wasm::WASM_SYMBOL_TYPE_GLOBAL
) {
446 IO
.mapRequired("Global", Info
.ElementIndex
);
447 } else if (Info
.Kind
== wasm::WASM_SYMBOL_TYPE_EVENT
) {
448 IO
.mapRequired("Event", Info
.ElementIndex
);
449 } else if (Info
.Kind
== wasm::WASM_SYMBOL_TYPE_DATA
) {
450 if ((Info
.Flags
& wasm::WASM_SYMBOL_UNDEFINED
) == 0) {
451 IO
.mapRequired("Segment", Info
.DataRef
.Segment
);
452 IO
.mapOptional("Offset", Info
.DataRef
.Offset
, 0u);
453 IO
.mapRequired("Size", Info
.DataRef
.Size
);
455 } else if (Info
.Kind
== wasm::WASM_SYMBOL_TYPE_SECTION
) {
456 IO
.mapRequired("Section", Info
.ElementIndex
);
458 llvm_unreachable("unsupported symbol kind");
462 void MappingTraits
<WasmYAML::Event
>::mapping(IO
&IO
, WasmYAML::Event
&Event
) {
463 IO
.mapRequired("Index", Event
.Index
);
464 IO
.mapRequired("Attribute", Event
.Attribute
);
465 IO
.mapRequired("SigIndex", Event
.SigIndex
);
468 void ScalarBitSetTraits
<WasmYAML::LimitFlags
>::bitset(
469 IO
&IO
, WasmYAML::LimitFlags
&Value
) {
470 #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X)
476 void ScalarBitSetTraits
<WasmYAML::SegmentFlags
>::bitset(
477 IO
&IO
, WasmYAML::SegmentFlags
&Value
) {}
479 void ScalarBitSetTraits
<WasmYAML::SymbolFlags
>::bitset(
480 IO
&IO
, WasmYAML::SymbolFlags
&Value
) {
481 #define BCaseMask(M, X) \
482 IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M)
483 // BCaseMask(BINDING_MASK, BINDING_GLOBAL);
484 BCaseMask(BINDING_MASK
, BINDING_WEAK
);
485 BCaseMask(BINDING_MASK
, BINDING_LOCAL
);
486 // BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT);
487 BCaseMask(VISIBILITY_MASK
, VISIBILITY_HIDDEN
);
488 BCaseMask(UNDEFINED
, UNDEFINED
);
489 BCaseMask(EXPORTED
, EXPORTED
);
493 void ScalarEnumerationTraits
<WasmYAML::SymbolKind
>::enumeration(
494 IO
&IO
, WasmYAML::SymbolKind
&Kind
) {
495 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X);
504 void ScalarEnumerationTraits
<WasmYAML::ValueType
>::enumeration(
505 IO
&IO
, WasmYAML::ValueType
&Type
) {
506 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
518 void ScalarEnumerationTraits
<WasmYAML::ExportKind
>::enumeration(
519 IO
&IO
, WasmYAML::ExportKind
&Kind
) {
520 #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X);
529 void ScalarEnumerationTraits
<WasmYAML::Opcode
>::enumeration(
530 IO
&IO
, WasmYAML::Opcode
&Code
) {
531 #define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X);
541 void ScalarEnumerationTraits
<WasmYAML::TableType
>::enumeration(
542 IO
&IO
, WasmYAML::TableType
&Type
) {
543 #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
548 void ScalarEnumerationTraits
<WasmYAML::RelocType
>::enumeration(
549 IO
&IO
, WasmYAML::RelocType
&Type
) {
550 #define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name);
551 #include "llvm/BinaryFormat/WasmRelocs.def"
555 } // end namespace yaml
557 } // end namespace llvm