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