1 | //===- WasmYAML.cpp - Wasm YAMLIO implementation --------------------------===// |
2 | // |
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 |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines classes for handling the YAML representation of wasm. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/ObjectYAML/WasmYAML.h" |
14 | #include "llvm/ADT/StringRef.h" |
15 | #include "llvm/BinaryFormat/Wasm.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>::( |
33 | IO &IO, WasmYAML::FileHeader &FileHdr) { |
34 | IO.mapRequired(Key: "Version" , Val&: FileHdr.Version); |
35 | } |
36 | |
37 | void MappingTraits<WasmYAML::Object>::mapping(IO &IO, |
38 | WasmYAML::Object &Object) { |
39 | IO.setContext(&Object); |
40 | IO.mapTag(Tag: "!WASM" , Default: true); |
41 | IO.mapRequired(Key: "FileHeader" , Val&: Object.Header); |
42 | IO.mapOptional(Key: "Sections" , Val&: Object.Sections); |
43 | IO.setContext(nullptr); |
44 | } |
45 | |
46 | static void commonSectionMapping(IO &IO, WasmYAML::Section &Section) { |
47 | IO.mapRequired(Key: "Type" , Val&: Section.Type); |
48 | IO.mapOptional(Key: "Relocations" , Val&: Section.Relocations); |
49 | IO.mapOptional(Key: "HeaderSecSizeEncodingLen" , Val&: Section.HeaderSecSizeEncodingLen); |
50 | } |
51 | |
52 | static void sectionMapping(IO &IO, WasmYAML::DylinkSection &Section) { |
53 | commonSectionMapping(IO, Section); |
54 | IO.mapRequired(Key: "Name" , Val&: Section.Name); |
55 | IO.mapRequired(Key: "MemorySize" , Val&: Section.MemorySize); |
56 | IO.mapRequired(Key: "MemoryAlignment" , Val&: Section.MemoryAlignment); |
57 | IO.mapRequired(Key: "TableSize" , Val&: Section.TableSize); |
58 | IO.mapRequired(Key: "TableAlignment" , Val&: Section.TableAlignment); |
59 | IO.mapRequired(Key: "Needed" , Val&: Section.Needed); |
60 | IO.mapOptional(Key: "ImportInfo" , Val&: Section.ImportInfo); |
61 | IO.mapOptional(Key: "ExportInfo" , Val&: Section.ExportInfo); |
62 | IO.mapOptional(Key: "RuntimePath" , Val&: Section.RuntimePath); |
63 | } |
64 | |
65 | static void sectionMapping(IO &IO, WasmYAML::NameSection &Section) { |
66 | commonSectionMapping(IO, Section); |
67 | IO.mapRequired(Key: "Name" , Val&: Section.Name); |
68 | IO.mapOptional(Key: "FunctionNames" , Val&: Section.FunctionNames); |
69 | IO.mapOptional(Key: "GlobalNames" , Val&: Section.GlobalNames); |
70 | IO.mapOptional(Key: "DataSegmentNames" , Val&: Section.DataSegmentNames); |
71 | } |
72 | |
73 | static void sectionMapping(IO &IO, WasmYAML::LinkingSection &Section) { |
74 | commonSectionMapping(IO, Section); |
75 | IO.mapRequired(Key: "Name" , Val&: Section.Name); |
76 | IO.mapRequired(Key: "Version" , Val&: Section.Version); |
77 | IO.mapOptional(Key: "SymbolTable" , Val&: Section.SymbolTable); |
78 | IO.mapOptional(Key: "SegmentInfo" , Val&: Section.SegmentInfos); |
79 | IO.mapOptional(Key: "InitFunctions" , Val&: Section.InitFunctions); |
80 | IO.mapOptional(Key: "Comdats" , Val&: Section.Comdats); |
81 | } |
82 | |
83 | static void (IO &IO, WasmYAML::ProducersSection &Section) { |
84 | commonSectionMapping(IO, Section); |
85 | IO.mapRequired(Key: "Name" , Val&: Section.Name); |
86 | IO.mapOptional(Key: "Languages" , Val&: Section.Languages); |
87 | IO.mapOptional(Key: "Tools" , Val&: Section.Tools); |
88 | IO.mapOptional(Key: "SDKs" , Val&: Section.SDKs); |
89 | } |
90 | |
91 | static void sectionMapping(IO &IO, WasmYAML::TargetFeaturesSection &Section) { |
92 | commonSectionMapping(IO, Section); |
93 | IO.mapRequired(Key: "Name" , Val&: Section.Name); |
94 | IO.mapRequired(Key: "Features" , Val&: Section.Features); |
95 | } |
96 | |
97 | static void sectionMapping(IO &IO, WasmYAML::CustomSection &Section) { |
98 | commonSectionMapping(IO, Section); |
99 | IO.mapRequired(Key: "Name" , Val&: Section.Name); |
100 | IO.mapRequired(Key: "Payload" , Val&: Section.Payload); |
101 | } |
102 | |
103 | static void sectionMapping(IO &IO, WasmYAML::TypeSection &Section) { |
104 | commonSectionMapping(IO, Section); |
105 | IO.mapOptional(Key: "Signatures" , Val&: Section.Signatures); |
106 | } |
107 | |
108 | static void sectionMapping(IO &IO, WasmYAML::ImportSection &Section) { |
109 | commonSectionMapping(IO, Section); |
110 | IO.mapOptional(Key: "Imports" , Val&: Section.Imports); |
111 | } |
112 | |
113 | static void sectionMapping(IO &IO, WasmYAML::FunctionSection &Section) { |
114 | commonSectionMapping(IO, Section); |
115 | IO.mapOptional(Key: "FunctionTypes" , Val&: Section.FunctionTypes); |
116 | } |
117 | |
118 | static void sectionMapping(IO &IO, WasmYAML::TableSection &Section) { |
119 | commonSectionMapping(IO, Section); |
120 | IO.mapOptional(Key: "Tables" , Val&: Section.Tables); |
121 | } |
122 | |
123 | static void sectionMapping(IO &IO, WasmYAML::MemorySection &Section) { |
124 | commonSectionMapping(IO, Section); |
125 | IO.mapOptional(Key: "Memories" , Val&: Section.Memories); |
126 | } |
127 | |
128 | static void sectionMapping(IO &IO, WasmYAML::TagSection &Section) { |
129 | commonSectionMapping(IO, Section); |
130 | IO.mapOptional(Key: "TagTypes" , Val&: Section.TagTypes); |
131 | } |
132 | |
133 | static void sectionMapping(IO &IO, WasmYAML::GlobalSection &Section) { |
134 | commonSectionMapping(IO, Section); |
135 | IO.mapOptional(Key: "Globals" , Val&: Section.Globals); |
136 | } |
137 | |
138 | static void sectionMapping(IO &IO, WasmYAML::ExportSection &Section) { |
139 | commonSectionMapping(IO, Section); |
140 | IO.mapOptional(Key: "Exports" , Val&: Section.Exports); |
141 | } |
142 | |
143 | static void sectionMapping(IO &IO, WasmYAML::StartSection &Section) { |
144 | commonSectionMapping(IO, Section); |
145 | IO.mapOptional(Key: "StartFunction" , Val&: Section.StartFunction); |
146 | } |
147 | |
148 | static void sectionMapping(IO &IO, WasmYAML::ElemSection &Section) { |
149 | commonSectionMapping(IO, Section); |
150 | IO.mapOptional(Key: "Segments" , Val&: Section.Segments); |
151 | } |
152 | |
153 | static void sectionMapping(IO &IO, WasmYAML::CodeSection &Section) { |
154 | commonSectionMapping(IO, Section); |
155 | IO.mapRequired(Key: "Functions" , Val&: Section.Functions); |
156 | } |
157 | |
158 | static void sectionMapping(IO &IO, WasmYAML::DataSection &Section) { |
159 | commonSectionMapping(IO, Section); |
160 | IO.mapRequired(Key: "Segments" , Val&: Section.Segments); |
161 | } |
162 | |
163 | static void sectionMapping(IO &IO, WasmYAML::DataCountSection &Section) { |
164 | commonSectionMapping(IO, Section); |
165 | IO.mapRequired(Key: "Count" , Val&: Section.Count); |
166 | } |
167 | |
168 | void MappingTraits<std::unique_ptr<WasmYAML::Section>>::mapping( |
169 | IO &IO, std::unique_ptr<WasmYAML::Section> &Section) { |
170 | WasmYAML::SectionType SectionType; |
171 | if (IO.outputting()) |
172 | SectionType = Section->Type; |
173 | else |
174 | IO.mapRequired(Key: "Type" , Val&: SectionType); |
175 | |
176 | switch (SectionType) { |
177 | case wasm::WASM_SEC_CUSTOM: { |
178 | StringRef SectionName; |
179 | if (IO.outputting()) { |
180 | auto CustomSection = cast<WasmYAML::CustomSection>(Val: Section.get()); |
181 | SectionName = CustomSection->Name; |
182 | } else { |
183 | IO.mapRequired(Key: "Name" , Val&: SectionName); |
184 | } |
185 | if (SectionName == "dylink" || SectionName == "dylink.0" ) { |
186 | if (!IO.outputting()) |
187 | Section.reset(p: new WasmYAML::DylinkSection()); |
188 | sectionMapping(IO, Section&: *cast<WasmYAML::DylinkSection>(Val: Section.get())); |
189 | } else if (SectionName == "linking" ) { |
190 | if (!IO.outputting()) |
191 | Section.reset(p: new WasmYAML::LinkingSection()); |
192 | sectionMapping(IO, Section&: *cast<WasmYAML::LinkingSection>(Val: Section.get())); |
193 | } else if (SectionName == "name" ) { |
194 | if (!IO.outputting()) |
195 | Section.reset(p: new WasmYAML::NameSection()); |
196 | sectionMapping(IO, Section&: *cast<WasmYAML::NameSection>(Val: Section.get())); |
197 | } else if (SectionName == "producers" ) { |
198 | if (!IO.outputting()) |
199 | Section.reset(p: new WasmYAML::ProducersSection()); |
200 | sectionMapping(IO, Section&: *cast<WasmYAML::ProducersSection>(Val: Section.get())); |
201 | } else if (SectionName == "target_features" ) { |
202 | if (!IO.outputting()) |
203 | Section.reset(p: new WasmYAML::TargetFeaturesSection()); |
204 | sectionMapping(IO, Section&: *cast<WasmYAML::TargetFeaturesSection>(Val: Section.get())); |
205 | } else { |
206 | if (!IO.outputting()) |
207 | Section.reset(p: new WasmYAML::CustomSection(SectionName)); |
208 | sectionMapping(IO, Section&: *cast<WasmYAML::CustomSection>(Val: Section.get())); |
209 | } |
210 | break; |
211 | } |
212 | case wasm::WASM_SEC_TYPE: |
213 | if (!IO.outputting()) |
214 | Section.reset(p: new WasmYAML::TypeSection()); |
215 | sectionMapping(IO, Section&: *cast<WasmYAML::TypeSection>(Val: Section.get())); |
216 | break; |
217 | case wasm::WASM_SEC_IMPORT: |
218 | if (!IO.outputting()) |
219 | Section.reset(p: new WasmYAML::ImportSection()); |
220 | sectionMapping(IO, Section&: *cast<WasmYAML::ImportSection>(Val: Section.get())); |
221 | break; |
222 | case wasm::WASM_SEC_FUNCTION: |
223 | if (!IO.outputting()) |
224 | Section.reset(p: new WasmYAML::FunctionSection()); |
225 | sectionMapping(IO, Section&: *cast<WasmYAML::FunctionSection>(Val: Section.get())); |
226 | break; |
227 | case wasm::WASM_SEC_TABLE: |
228 | if (!IO.outputting()) |
229 | Section.reset(p: new WasmYAML::TableSection()); |
230 | sectionMapping(IO, Section&: *cast<WasmYAML::TableSection>(Val: Section.get())); |
231 | break; |
232 | case wasm::WASM_SEC_MEMORY: |
233 | if (!IO.outputting()) |
234 | Section.reset(p: new WasmYAML::MemorySection()); |
235 | sectionMapping(IO, Section&: *cast<WasmYAML::MemorySection>(Val: Section.get())); |
236 | break; |
237 | case wasm::WASM_SEC_TAG: |
238 | if (!IO.outputting()) |
239 | Section.reset(p: new WasmYAML::TagSection()); |
240 | sectionMapping(IO, Section&: *cast<WasmYAML::TagSection>(Val: Section.get())); |
241 | break; |
242 | case wasm::WASM_SEC_GLOBAL: |
243 | if (!IO.outputting()) |
244 | Section.reset(p: new WasmYAML::GlobalSection()); |
245 | sectionMapping(IO, Section&: *cast<WasmYAML::GlobalSection>(Val: Section.get())); |
246 | break; |
247 | case wasm::WASM_SEC_EXPORT: |
248 | if (!IO.outputting()) |
249 | Section.reset(p: new WasmYAML::ExportSection()); |
250 | sectionMapping(IO, Section&: *cast<WasmYAML::ExportSection>(Val: Section.get())); |
251 | break; |
252 | case wasm::WASM_SEC_START: |
253 | if (!IO.outputting()) |
254 | Section.reset(p: new WasmYAML::StartSection()); |
255 | sectionMapping(IO, Section&: *cast<WasmYAML::StartSection>(Val: Section.get())); |
256 | break; |
257 | case wasm::WASM_SEC_ELEM: |
258 | if (!IO.outputting()) |
259 | Section.reset(p: new WasmYAML::ElemSection()); |
260 | sectionMapping(IO, Section&: *cast<WasmYAML::ElemSection>(Val: Section.get())); |
261 | break; |
262 | case wasm::WASM_SEC_CODE: |
263 | if (!IO.outputting()) |
264 | Section.reset(p: new WasmYAML::CodeSection()); |
265 | sectionMapping(IO, Section&: *cast<WasmYAML::CodeSection>(Val: Section.get())); |
266 | break; |
267 | case wasm::WASM_SEC_DATA: |
268 | if (!IO.outputting()) |
269 | Section.reset(p: new WasmYAML::DataSection()); |
270 | sectionMapping(IO, Section&: *cast<WasmYAML::DataSection>(Val: Section.get())); |
271 | break; |
272 | case wasm::WASM_SEC_DATACOUNT: |
273 | if (!IO.outputting()) |
274 | Section.reset(p: new WasmYAML::DataCountSection()); |
275 | sectionMapping(IO, Section&: *cast<WasmYAML::DataCountSection>(Val: Section.get())); |
276 | break; |
277 | default: |
278 | llvm_unreachable("Unknown section type" ); |
279 | } |
280 | } |
281 | |
282 | void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration( |
283 | IO &IO, WasmYAML::SectionType &Type) { |
284 | #define ECase(X) IO.enumCase(Type, #X, wasm::WASM_SEC_##X); |
285 | ECase(CUSTOM); |
286 | ECase(TYPE); |
287 | ECase(IMPORT); |
288 | ECase(FUNCTION); |
289 | ECase(TABLE); |
290 | ECase(MEMORY); |
291 | ECase(GLOBAL); |
292 | ECase(TAG); |
293 | ECase(EXPORT); |
294 | ECase(START); |
295 | ECase(ELEM); |
296 | ECase(CODE); |
297 | ECase(DATA); |
298 | ECase(DATACOUNT); |
299 | #undef ECase |
300 | } |
301 | |
302 | void MappingTraits<WasmYAML::Signature>::mapping( |
303 | IO &IO, WasmYAML::Signature &Signature) { |
304 | IO.mapRequired(Key: "Index" , Val&: Signature.Index); |
305 | IO.mapRequired(Key: "ParamTypes" , Val&: Signature.ParamTypes); |
306 | IO.mapRequired(Key: "ReturnTypes" , Val&: Signature.ReturnTypes); |
307 | } |
308 | |
309 | void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) { |
310 | IO.mapRequired(Key: "Index" , Val&: Table.Index); |
311 | IO.mapRequired(Key: "ElemType" , Val&: Table.ElemType); |
312 | IO.mapRequired(Key: "Limits" , Val&: Table.TableLimits); |
313 | } |
314 | |
315 | void MappingTraits<WasmYAML::Function>::mapping(IO &IO, |
316 | WasmYAML::Function &Function) { |
317 | IO.mapRequired(Key: "Index" , Val&: Function.Index); |
318 | IO.mapRequired(Key: "Locals" , Val&: Function.Locals); |
319 | IO.mapRequired(Key: "Body" , Val&: Function.Body); |
320 | } |
321 | |
322 | void MappingTraits<WasmYAML::Relocation>::mapping( |
323 | IO &IO, WasmYAML::Relocation &Relocation) { |
324 | IO.mapRequired(Key: "Type" , Val&: Relocation.Type); |
325 | IO.mapRequired(Key: "Index" , Val&: Relocation.Index); |
326 | IO.mapRequired(Key: "Offset" , Val&: Relocation.Offset); |
327 | IO.mapOptional(Key: "Addend" , Val&: Relocation.Addend, Default: 0); |
328 | } |
329 | |
330 | void MappingTraits<WasmYAML::NameEntry>::mapping( |
331 | IO &IO, WasmYAML::NameEntry &NameEntry) { |
332 | IO.mapRequired(Key: "Index" , Val&: NameEntry.Index); |
333 | IO.mapRequired(Key: "Name" , Val&: NameEntry.Name); |
334 | } |
335 | |
336 | void MappingTraits<WasmYAML::ProducerEntry>::mapping( |
337 | IO &IO, WasmYAML::ProducerEntry &ProducerEntry) { |
338 | IO.mapRequired(Key: "Name" , Val&: ProducerEntry.Name); |
339 | IO.mapRequired(Key: "Version" , Val&: ProducerEntry.Version); |
340 | } |
341 | |
342 | void ScalarEnumerationTraits<WasmYAML::FeaturePolicyPrefix>::enumeration( |
343 | IO &IO, WasmYAML::FeaturePolicyPrefix &Kind) { |
344 | #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_FEATURE_PREFIX_##X); |
345 | ECase(USED); |
346 | ECase(DISALLOWED); |
347 | #undef ECase |
348 | } |
349 | |
350 | void MappingTraits<WasmYAML::FeatureEntry>::mapping( |
351 | IO &IO, WasmYAML::FeatureEntry &FeatureEntry) { |
352 | IO.mapRequired(Key: "Prefix" , Val&: FeatureEntry.Prefix); |
353 | IO.mapRequired(Key: "Name" , Val&: FeatureEntry.Name); |
354 | } |
355 | |
356 | void MappingTraits<WasmYAML::SegmentInfo>::mapping( |
357 | IO &IO, WasmYAML::SegmentInfo &SegmentInfo) { |
358 | IO.mapRequired(Key: "Index" , Val&: SegmentInfo.Index); |
359 | IO.mapRequired(Key: "Name" , Val&: SegmentInfo.Name); |
360 | IO.mapRequired(Key: "Alignment" , Val&: SegmentInfo.Alignment); |
361 | IO.mapRequired(Key: "Flags" , Val&: SegmentInfo.Flags); |
362 | } |
363 | |
364 | void MappingTraits<WasmYAML::LocalDecl>::mapping( |
365 | IO &IO, WasmYAML::LocalDecl &LocalDecl) { |
366 | IO.mapRequired(Key: "Type" , Val&: LocalDecl.Type); |
367 | IO.mapRequired(Key: "Count" , Val&: LocalDecl.Count); |
368 | } |
369 | |
370 | void MappingTraits<WasmYAML::Limits>::mapping(IO &IO, |
371 | WasmYAML::Limits &Limits) { |
372 | IO.mapOptional(Key: "Flags" , Val&: Limits.Flags, Default: 0); |
373 | IO.mapRequired(Key: "Minimum" , Val&: Limits.Minimum); |
374 | if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX) |
375 | IO.mapOptional(Key: "Maximum" , Val&: Limits.Maximum); |
376 | if (!IO.outputting() || Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_PAGE_SIZE) |
377 | IO.mapOptional(Key: "PageSize" , Val&: Limits.PageSize); |
378 | } |
379 | |
380 | void MappingTraits<WasmYAML::ElemSegment>::mapping( |
381 | IO &IO, WasmYAML::ElemSegment &Segment) { |
382 | IO.mapOptional(Key: "Flags" , Val&: Segment.Flags, Default: 0); |
383 | if (!IO.outputting() || |
384 | Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER) |
385 | IO.mapOptional(Key: "TableNumber" , Val&: Segment.TableNumber); |
386 | if (!IO.outputting() || |
387 | Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_DESC) |
388 | IO.mapOptional(Key: "ElemKind" , Val&: Segment.ElemKind); |
389 | // TODO: Omit "offset" for passive segments? It's neither meaningful nor |
390 | // encoded. |
391 | IO.mapRequired(Key: "Offset" , Val&: Segment.Offset); |
392 | IO.mapRequired(Key: "Functions" , Val&: Segment.Functions); |
393 | } |
394 | |
395 | void MappingTraits<WasmYAML::Import>::mapping(IO &IO, |
396 | WasmYAML::Import &Import) { |
397 | IO.mapRequired(Key: "Module" , Val&: Import.Module); |
398 | IO.mapRequired(Key: "Field" , Val&: Import.Field); |
399 | IO.mapRequired(Key: "Kind" , Val&: Import.Kind); |
400 | if (Import.Kind == wasm::WASM_EXTERNAL_FUNCTION || |
401 | Import.Kind == wasm::WASM_EXTERNAL_TAG) { |
402 | IO.mapRequired(Key: "SigIndex" , Val&: Import.SigIndex); |
403 | } else if (Import.Kind == wasm::WASM_EXTERNAL_GLOBAL) { |
404 | IO.mapRequired(Key: "GlobalType" , Val&: Import.GlobalImport.Type); |
405 | IO.mapRequired(Key: "GlobalMutable" , Val&: Import.GlobalImport.Mutable); |
406 | } else if (Import.Kind == wasm::WASM_EXTERNAL_TABLE) { |
407 | IO.mapRequired(Key: "Table" , Val&: Import.TableImport); |
408 | } else if (Import.Kind == wasm::WASM_EXTERNAL_MEMORY) { |
409 | IO.mapRequired(Key: "Memory" , Val&: Import.Memory); |
410 | } else { |
411 | llvm_unreachable("unhandled import type" ); |
412 | } |
413 | } |
414 | |
415 | void MappingTraits<WasmYAML::Export>::mapping(IO &IO, |
416 | WasmYAML::Export &Export) { |
417 | IO.mapRequired(Key: "Name" , Val&: Export.Name); |
418 | IO.mapRequired(Key: "Kind" , Val&: Export.Kind); |
419 | IO.mapRequired(Key: "Index" , Val&: Export.Index); |
420 | } |
421 | |
422 | void MappingTraits<WasmYAML::Global>::mapping(IO &IO, |
423 | WasmYAML::Global &Global) { |
424 | IO.mapRequired(Key: "Index" , Val&: Global.Index); |
425 | IO.mapRequired(Key: "Type" , Val&: Global.Type); |
426 | IO.mapRequired(Key: "Mutable" , Val&: Global.Mutable); |
427 | IO.mapRequired(Key: "InitExpr" , Val&: Global.Init); |
428 | } |
429 | |
430 | void MappingTraits<WasmYAML::InitExpr>::mapping(IO &IO, |
431 | WasmYAML::InitExpr &Expr) { |
432 | IO.mapOptional(Key: "Extended" , Val&: Expr.Extended, Default: false); |
433 | if (Expr.Extended) { |
434 | IO.mapRequired(Key: "Body" , Val&: Expr.Body); |
435 | } else { |
436 | WasmYAML::Opcode Op = Expr.Inst.Opcode; |
437 | IO.mapRequired(Key: "Opcode" , Val&: Op); |
438 | Expr.Inst.Opcode = Op; |
439 | switch (Expr.Inst.Opcode) { |
440 | case wasm::WASM_OPCODE_I32_CONST: |
441 | IO.mapRequired(Key: "Value" , Val&: Expr.Inst.Value.Int32); |
442 | break; |
443 | case wasm::WASM_OPCODE_I64_CONST: |
444 | IO.mapRequired(Key: "Value" , Val&: Expr.Inst.Value.Int64); |
445 | break; |
446 | case wasm::WASM_OPCODE_F32_CONST: |
447 | IO.mapRequired(Key: "Value" , Val&: Expr.Inst.Value.Float32); |
448 | break; |
449 | case wasm::WASM_OPCODE_F64_CONST: |
450 | IO.mapRequired(Key: "Value" , Val&: Expr.Inst.Value.Float64); |
451 | break; |
452 | case wasm::WASM_OPCODE_GLOBAL_GET: |
453 | IO.mapRequired(Key: "Index" , Val&: Expr.Inst.Value.Global); |
454 | break; |
455 | case wasm::WASM_OPCODE_REF_NULL: { |
456 | WasmYAML::ValueType Ty = wasm::WASM_TYPE_EXTERNREF; |
457 | IO.mapRequired(Key: "Type" , Val&: Ty); |
458 | break; |
459 | } |
460 | } |
461 | } |
462 | } |
463 | |
464 | void MappingTraits<WasmYAML::DataSegment>::mapping( |
465 | IO &IO, WasmYAML::DataSegment &Segment) { |
466 | IO.mapOptional(Key: "SectionOffset" , Val&: Segment.SectionOffset); |
467 | IO.mapRequired(Key: "InitFlags" , Val&: Segment.InitFlags); |
468 | if (Segment.InitFlags & wasm::WASM_DATA_SEGMENT_HAS_MEMINDEX) { |
469 | IO.mapRequired(Key: "MemoryIndex" , Val&: Segment.MemoryIndex); |
470 | } else { |
471 | Segment.MemoryIndex = 0; |
472 | } |
473 | if ((Segment.InitFlags & wasm::WASM_DATA_SEGMENT_IS_PASSIVE) == 0) { |
474 | IO.mapRequired(Key: "Offset" , Val&: Segment.Offset); |
475 | } else { |
476 | Segment.Offset.Inst.Opcode = wasm::WASM_OPCODE_I32_CONST; |
477 | Segment.Offset.Inst.Value.Int32 = 0; |
478 | } |
479 | IO.mapRequired(Key: "Content" , Val&: Segment.Content); |
480 | } |
481 | |
482 | void MappingTraits<WasmYAML::InitFunction>::mapping( |
483 | IO &IO, WasmYAML::InitFunction &Init) { |
484 | IO.mapRequired(Key: "Priority" , Val&: Init.Priority); |
485 | IO.mapRequired(Key: "Symbol" , Val&: Init.Symbol); |
486 | } |
487 | |
488 | void ScalarEnumerationTraits<WasmYAML::ComdatKind>::enumeration( |
489 | IO &IO, WasmYAML::ComdatKind &Kind) { |
490 | #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_COMDAT_##X); |
491 | ECase(FUNCTION); |
492 | ECase(DATA); |
493 | ECase(SECTION); |
494 | #undef ECase |
495 | } |
496 | |
497 | void MappingTraits<WasmYAML::ComdatEntry>::mapping( |
498 | IO &IO, WasmYAML::ComdatEntry &ComdatEntry) { |
499 | IO.mapRequired(Key: "Kind" , Val&: ComdatEntry.Kind); |
500 | IO.mapRequired(Key: "Index" , Val&: ComdatEntry.Index); |
501 | } |
502 | |
503 | void MappingTraits<WasmYAML::Comdat>::mapping(IO &IO, |
504 | WasmYAML::Comdat &Comdat) { |
505 | IO.mapRequired(Key: "Name" , Val&: Comdat.Name); |
506 | IO.mapRequired(Key: "Entries" , Val&: Comdat.Entries); |
507 | } |
508 | |
509 | void MappingTraits<WasmYAML::SymbolInfo>::mapping(IO &IO, |
510 | WasmYAML::SymbolInfo &Info) { |
511 | IO.mapRequired(Key: "Index" , Val&: Info.Index); |
512 | IO.mapRequired(Key: "Kind" , Val&: Info.Kind); |
513 | if (Info.Kind != wasm::WASM_SYMBOL_TYPE_SECTION) |
514 | IO.mapRequired(Key: "Name" , Val&: Info.Name); |
515 | IO.mapRequired(Key: "Flags" , Val&: Info.Flags); |
516 | if (Info.Kind == wasm::WASM_SYMBOL_TYPE_FUNCTION) { |
517 | IO.mapRequired(Key: "Function" , Val&: Info.ElementIndex); |
518 | } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_GLOBAL) { |
519 | IO.mapRequired(Key: "Global" , Val&: Info.ElementIndex); |
520 | } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE) { |
521 | IO.mapRequired(Key: "Table" , Val&: Info.ElementIndex); |
522 | } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TAG) { |
523 | IO.mapRequired(Key: "Tag" , Val&: Info.ElementIndex); |
524 | } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) { |
525 | if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) { |
526 | if ((Info.Flags & wasm::WASM_SYMBOL_ABSOLUTE) == 0) { |
527 | IO.mapRequired(Key: "Segment" , Val&: Info.DataRef.Segment); |
528 | } |
529 | IO.mapOptional(Key: "Offset" , Val&: Info.DataRef.Offset, Default: 0u); |
530 | IO.mapRequired(Key: "Size" , Val&: Info.DataRef.Size); |
531 | } |
532 | } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_SECTION) { |
533 | IO.mapRequired(Key: "Section" , Val&: Info.ElementIndex); |
534 | } else { |
535 | llvm_unreachable("unsupported symbol kind" ); |
536 | } |
537 | } |
538 | |
539 | void MappingTraits<WasmYAML::DylinkImportInfo>::mapping( |
540 | IO &IO, WasmYAML::DylinkImportInfo &Info) { |
541 | IO.mapRequired(Key: "Module" , Val&: Info.Module); |
542 | IO.mapRequired(Key: "Field" , Val&: Info.Field); |
543 | IO.mapRequired(Key: "Flags" , Val&: Info.Flags); |
544 | } |
545 | |
546 | void MappingTraits<WasmYAML::DylinkExportInfo>::mapping( |
547 | IO &IO, WasmYAML::DylinkExportInfo &Info) { |
548 | IO.mapRequired(Key: "Name" , Val&: Info.Name); |
549 | IO.mapRequired(Key: "Flags" , Val&: Info.Flags); |
550 | } |
551 | |
552 | void ScalarBitSetTraits<WasmYAML::LimitFlags>::bitset( |
553 | IO &IO, WasmYAML::LimitFlags &Value) { |
554 | #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_LIMITS_FLAG_##X) |
555 | BCase(HAS_MAX); |
556 | BCase(IS_SHARED); |
557 | BCase(IS_64); |
558 | BCase(HAS_PAGE_SIZE); |
559 | #undef BCase |
560 | } |
561 | |
562 | void ScalarBitSetTraits<WasmYAML::SegmentFlags>::bitset( |
563 | IO &IO, WasmYAML::SegmentFlags &Value) { |
564 | #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_SEG_FLAG_##X) |
565 | BCase(STRINGS); |
566 | BCase(TLS); |
567 | BCase(RETAIN); |
568 | #undef BCase |
569 | } |
570 | |
571 | void ScalarBitSetTraits<WasmYAML::SymbolFlags>::bitset( |
572 | IO &IO, WasmYAML::SymbolFlags &Value) { |
573 | #define BCaseMask(M, X) \ |
574 | IO.maskedBitSetCase(Value, #X, wasm::WASM_SYMBOL_##X, wasm::WASM_SYMBOL_##M) |
575 | // BCaseMask(BINDING_MASK, BINDING_GLOBAL); |
576 | BCaseMask(BINDING_MASK, BINDING_WEAK); |
577 | BCaseMask(BINDING_MASK, BINDING_LOCAL); |
578 | // BCaseMask(VISIBILITY_MASK, VISIBILITY_DEFAULT); |
579 | BCaseMask(VISIBILITY_MASK, VISIBILITY_HIDDEN); |
580 | BCaseMask(UNDEFINED, UNDEFINED); |
581 | BCaseMask(EXPORTED, EXPORTED); |
582 | BCaseMask(EXPLICIT_NAME, EXPLICIT_NAME); |
583 | BCaseMask(NO_STRIP, NO_STRIP); |
584 | BCaseMask(TLS, TLS); |
585 | BCaseMask(ABSOLUTE, ABSOLUTE); |
586 | #undef BCaseMask |
587 | } |
588 | |
589 | void ScalarEnumerationTraits<WasmYAML::SymbolKind>::enumeration( |
590 | IO &IO, WasmYAML::SymbolKind &Kind) { |
591 | #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_SYMBOL_TYPE_##X); |
592 | ECase(FUNCTION); |
593 | ECase(DATA); |
594 | ECase(GLOBAL); |
595 | ECase(TABLE); |
596 | ECase(SECTION); |
597 | ECase(TAG); |
598 | #undef ECase |
599 | } |
600 | |
601 | void ScalarEnumerationTraits<WasmYAML::ValueType>::enumeration( |
602 | IO &IO, WasmYAML::ValueType &Type) { |
603 | #define CONCAT(X) (uint32_t) wasm::ValType::X |
604 | #define ECase(X) IO.enumCase(Type, #X, CONCAT(X)); |
605 | ECase(I32); |
606 | ECase(I64); |
607 | ECase(F32); |
608 | ECase(F64); |
609 | ECase(V128); |
610 | ECase(FUNCREF); |
611 | ECase(EXTERNREF); |
612 | ECase(EXNREF); |
613 | ECase(OTHERREF); |
614 | #undef ECase |
615 | } |
616 | |
617 | void ScalarEnumerationTraits<WasmYAML::ExportKind>::enumeration( |
618 | IO &IO, WasmYAML::ExportKind &Kind) { |
619 | #define ECase(X) IO.enumCase(Kind, #X, wasm::WASM_EXTERNAL_##X); |
620 | ECase(FUNCTION); |
621 | ECase(TABLE); |
622 | ECase(MEMORY); |
623 | ECase(GLOBAL); |
624 | ECase(TAG); |
625 | #undef ECase |
626 | } |
627 | |
628 | void ScalarEnumerationTraits<WasmYAML::Opcode>::enumeration( |
629 | IO &IO, WasmYAML::Opcode &Code) { |
630 | #define ECase(X) IO.enumCase(Code, #X, wasm::WASM_OPCODE_##X); |
631 | ECase(END); |
632 | ECase(I32_CONST); |
633 | ECase(I64_CONST); |
634 | ECase(F64_CONST); |
635 | ECase(F32_CONST); |
636 | ECase(GLOBAL_GET); |
637 | ECase(REF_NULL); |
638 | #undef ECase |
639 | } |
640 | |
641 | void ScalarEnumerationTraits<WasmYAML::TableType>::enumeration( |
642 | IO &IO, WasmYAML::TableType &Type) { |
643 | #define CONCAT(X) (uint32_t) wasm::ValType::X |
644 | #define ECase(X) IO.enumCase(Type, #X, CONCAT(X)); |
645 | ECase(FUNCREF); |
646 | ECase(EXTERNREF); |
647 | ECase(EXNREF); |
648 | ECase(OTHERREF); |
649 | #undef ECase |
650 | } |
651 | |
652 | void ScalarEnumerationTraits<WasmYAML::RelocType>::enumeration( |
653 | IO &IO, WasmYAML::RelocType &Type) { |
654 | #define WASM_RELOC(name, value) IO.enumCase(Type, #name, wasm::name); |
655 | #include "llvm/BinaryFormat/WasmRelocs.def" |
656 | #undef WASM_RELOC |
657 | IO.enumFallback<Hex32>(Val&: Type); |
658 | } |
659 | |
660 | } // end namespace yaml |
661 | |
662 | } // end namespace llvm |
663 | |