LLVM  10.0.0svn
WasmEmitter.cpp
Go to the documentation of this file.
1 //===- yaml2wasm - Convert YAML to a Wasm object file --------------------===//
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 /// \file
10 /// The Wasm component of yaml2obj.
11 ///
12 //===----------------------------------------------------------------------===//
13 //
14 
15 #include "llvm/Object/Wasm.h"
18 #include "llvm/Support/Endian.h"
19 #include "llvm/Support/LEB128.h"
20 
21 using namespace llvm;
22 
23 namespace {
24 /// This parses a yaml stream that represents a Wasm object file.
25 /// See docs/yaml2obj for the yaml scheema.
26 class WasmWriter {
27 public:
28  WasmWriter(WasmYAML::Object &Obj, yaml::ErrorHandler EH)
29  : Obj(Obj), ErrHandler(EH) {}
30  bool writeWasm(raw_ostream &OS);
31 
32 private:
33  void writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
34  uint32_t SectionIndex);
35 
36  void writeInitExpr(raw_ostream &OS, const wasm::WasmInitExpr &InitExpr);
37 
38  void writeSectionContent(raw_ostream &OS, WasmYAML::CustomSection &Section);
39  void writeSectionContent(raw_ostream &OS, WasmYAML::TypeSection &Section);
40  void writeSectionContent(raw_ostream &OS, WasmYAML::ImportSection &Section);
41  void writeSectionContent(raw_ostream &OS, WasmYAML::FunctionSection &Section);
42  void writeSectionContent(raw_ostream &OS, WasmYAML::TableSection &Section);
43  void writeSectionContent(raw_ostream &OS, WasmYAML::MemorySection &Section);
44  void writeSectionContent(raw_ostream &OS, WasmYAML::GlobalSection &Section);
45  void writeSectionContent(raw_ostream &OS, WasmYAML::EventSection &Section);
46  void writeSectionContent(raw_ostream &OS, WasmYAML::ExportSection &Section);
47  void writeSectionContent(raw_ostream &OS, WasmYAML::StartSection &Section);
48  void writeSectionContent(raw_ostream &OS, WasmYAML::ElemSection &Section);
49  void writeSectionContent(raw_ostream &OS, WasmYAML::CodeSection &Section);
50  void writeSectionContent(raw_ostream &OS, WasmYAML::DataSection &Section);
51  void writeSectionContent(raw_ostream &OS, WasmYAML::DataCountSection &Section);
52 
53  // Custom section types
54  void writeSectionContent(raw_ostream &OS, WasmYAML::DylinkSection &Section);
55  void writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
56  void writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
57  void writeSectionContent(raw_ostream &OS, WasmYAML::ProducersSection &Section);
58  void writeSectionContent(raw_ostream &OS,
60  WasmYAML::Object &Obj;
61  uint32_t NumImportedFunctions = 0;
62  uint32_t NumImportedGlobals = 0;
63  uint32_t NumImportedEvents = 0;
64 
65  bool HasError = false;
66  yaml::ErrorHandler ErrHandler;
67  void reportError(const Twine &Msg);
68 };
69 
70 class SubSectionWriter {
71  raw_ostream &OS;
72  std::string OutString;
73  raw_string_ostream StringStream;
74 
75 public:
76  SubSectionWriter(raw_ostream &OS) : OS(OS), StringStream(OutString) {}
77 
78  void done() {
79  StringStream.flush();
80  encodeULEB128(OutString.size(), OS);
81  OS << OutString;
82  OutString.clear();
83  }
84 
85  raw_ostream &getStream() { return StringStream; }
86 };
87 
88 } // end anonymous namespace
89 
90 static int writeUint64(raw_ostream &OS, uint64_t Value) {
91  char Data[sizeof(Value)];
93  OS.write(Data, sizeof(Data));
94  return 0;
95 }
96 
98  char Data[sizeof(Value)];
100  OS.write(Data, sizeof(Data));
101  return 0;
102 }
103 
104 static int writeUint8(raw_ostream &OS, uint8_t Value) {
105  char Data[sizeof(Value)];
106  memcpy(Data, &Value, sizeof(Data));
107  OS.write(Data, sizeof(Data));
108  return 0;
109 }
110 
111 static int writeStringRef(const StringRef &Str, raw_ostream &OS) {
112  encodeULEB128(Str.size(), OS);
113  OS << Str;
114  return 0;
115 }
116 
117 static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS) {
118  writeUint8(OS, Lim.Flags);
119  encodeULEB128(Lim.Initial, OS);
121  encodeULEB128(Lim.Maximum, OS);
122  return 0;
123 }
124 
125 void WasmWriter::reportError(const Twine &Msg) {
126  ErrHandler(Msg);
127  HasError = true;
128 }
129 
130 void WasmWriter::writeInitExpr(raw_ostream &OS,
131  const wasm::WasmInitExpr &InitExpr) {
132  writeUint8(OS, InitExpr.Opcode);
133  switch (InitExpr.Opcode) {
135  encodeSLEB128(InitExpr.Value.Int32, OS);
136  break;
138  encodeSLEB128(InitExpr.Value.Int64, OS);
139  break;
141  writeUint32(OS, InitExpr.Value.Float32);
142  break;
144  writeUint64(OS, InitExpr.Value.Float64);
145  break;
147  encodeULEB128(InitExpr.Value.Global, OS);
148  break;
149  default:
150  reportError("unknown opcode in init_expr: " + Twine(InitExpr.Opcode));
151  return;
152  }
154 }
155 
156 void WasmWriter::writeSectionContent(raw_ostream &OS,
158  writeStringRef(Section.Name, OS);
159  encodeULEB128(Section.MemorySize, OS);
160  encodeULEB128(Section.MemoryAlignment, OS);
161  encodeULEB128(Section.TableSize, OS);
162  encodeULEB128(Section.TableAlignment, OS);
163  encodeULEB128(Section.Needed.size(), OS);
164  for (StringRef Needed : Section.Needed)
165  writeStringRef(Needed, OS);
166 }
167 
168 void WasmWriter::writeSectionContent(raw_ostream &OS,
169  WasmYAML::LinkingSection &Section) {
170  writeStringRef(Section.Name, OS);
171  encodeULEB128(Section.Version, OS);
172 
173  SubSectionWriter SubSection(OS);
174 
175  // SYMBOL_TABLE subsection
176  if (Section.SymbolTable.size()) {
178 
179  encodeULEB128(Section.SymbolTable.size(), SubSection.getStream());
180 #ifndef NDEBUG
181  uint32_t SymbolIndex = 0;
182 #endif
183  for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) {
184  assert(Info.Index == SymbolIndex++);
185  writeUint8(SubSection.getStream(), Info.Kind);
186  encodeULEB128(Info.Flags, SubSection.getStream());
187  switch (Info.Kind) {
191  encodeULEB128(Info.ElementIndex, SubSection.getStream());
192  if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
194  writeStringRef(Info.Name, SubSection.getStream());
195  break;
197  writeStringRef(Info.Name, SubSection.getStream());
198  if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
199  encodeULEB128(Info.DataRef.Segment, SubSection.getStream());
200  encodeULEB128(Info.DataRef.Offset, SubSection.getStream());
201  encodeULEB128(Info.DataRef.Size, SubSection.getStream());
202  }
203  break;
205  encodeULEB128(Info.ElementIndex, SubSection.getStream());
206  break;
207  default:
208  llvm_unreachable("unexpected kind");
209  }
210  }
211 
212  SubSection.done();
213  }
214 
215  // SEGMENT_NAMES subsection
216  if (Section.SegmentInfos.size()) {
218  encodeULEB128(Section.SegmentInfos.size(), SubSection.getStream());
219  for (const WasmYAML::SegmentInfo &SegmentInfo : Section.SegmentInfos) {
220  writeStringRef(SegmentInfo.Name, SubSection.getStream());
221  encodeULEB128(SegmentInfo.Alignment, SubSection.getStream());
222  encodeULEB128(SegmentInfo.Flags, SubSection.getStream());
223  }
224  SubSection.done();
225  }
226 
227  // INIT_FUNCS subsection
228  if (Section.InitFunctions.size()) {
230  encodeULEB128(Section.InitFunctions.size(), SubSection.getStream());
231  for (const WasmYAML::InitFunction &Func : Section.InitFunctions) {
232  encodeULEB128(Func.Priority, SubSection.getStream());
233  encodeULEB128(Func.Symbol, SubSection.getStream());
234  }
235  SubSection.done();
236  }
237 
238  // COMDAT_INFO subsection
239  if (Section.Comdats.size()) {
241  encodeULEB128(Section.Comdats.size(), SubSection.getStream());
242  for (const auto &C : Section.Comdats) {
243  writeStringRef(C.Name, SubSection.getStream());
244  encodeULEB128(0, SubSection.getStream()); // flags for future use
245  encodeULEB128(C.Entries.size(), SubSection.getStream());
246  for (const WasmYAML::ComdatEntry &Entry : C.Entries) {
247  writeUint8(SubSection.getStream(), Entry.Kind);
248  encodeULEB128(Entry.Index, SubSection.getStream());
249  }
250  }
251  SubSection.done();
252  }
253 }
254 
255 void WasmWriter::writeSectionContent(raw_ostream &OS,
256  WasmYAML::NameSection &Section) {
257  writeStringRef(Section.Name, OS);
258  if (Section.FunctionNames.size()) {
260 
261  SubSectionWriter SubSection(OS);
262 
263  encodeULEB128(Section.FunctionNames.size(), SubSection.getStream());
264  for (const WasmYAML::NameEntry &NameEntry : Section.FunctionNames) {
265  encodeULEB128(NameEntry.Index, SubSection.getStream());
266  writeStringRef(NameEntry.Name, SubSection.getStream());
267  }
268 
269  SubSection.done();
270  }
271 }
272 
273 void WasmWriter::writeSectionContent(raw_ostream &OS,
274  WasmYAML::ProducersSection &Section) {
275  writeStringRef(Section.Name, OS);
276  int Fields = int(!Section.Languages.empty()) + int(!Section.Tools.empty()) +
277  int(!Section.SDKs.empty());
278  if (Fields == 0)
279  return;
280  encodeULEB128(Fields, OS);
281  for (auto &Field : {std::make_pair(StringRef("language"), &Section.Languages),
282  std::make_pair(StringRef("processed-by"), &Section.Tools),
283  std::make_pair(StringRef("sdk"), &Section.SDKs)}) {
284  if (Field.second->empty())
285  continue;
286  writeStringRef(Field.first, OS);
287  encodeULEB128(Field.second->size(), OS);
288  for (auto &Entry : *Field.second) {
290  writeStringRef(Entry.Version, OS);
291  }
292  }
293 }
294 
295 void WasmWriter::writeSectionContent(raw_ostream &OS,
297  writeStringRef(Section.Name, OS);
298  encodeULEB128(Section.Features.size(), OS);
299  for (auto &E : Section.Features) {
300  writeUint8(OS, E.Prefix);
301  writeStringRef(E.Name, OS);
302  }
303 }
304 
305 void WasmWriter::writeSectionContent(raw_ostream &OS,
306  WasmYAML::CustomSection &Section) {
307  if (auto S = dyn_cast<WasmYAML::DylinkSection>(&Section)) {
308  writeSectionContent(OS, *S);
309  } else if (auto S = dyn_cast<WasmYAML::NameSection>(&Section)) {
310  writeSectionContent(OS, *S);
311  } else if (auto S = dyn_cast<WasmYAML::LinkingSection>(&Section)) {
312  writeSectionContent(OS, *S);
313  } else if (auto S = dyn_cast<WasmYAML::ProducersSection>(&Section)) {
314  writeSectionContent(OS, *S);
315  } else if (auto S = dyn_cast<WasmYAML::TargetFeaturesSection>(&Section)) {
316  writeSectionContent(OS, *S);
317  } else {
318  writeStringRef(Section.Name, OS);
319  Section.Payload.writeAsBinary(OS);
320  }
321 }
322 
323 void WasmWriter::writeSectionContent(raw_ostream &OS,
324  WasmYAML::TypeSection &Section) {
325  encodeULEB128(Section.Signatures.size(), OS);
326  uint32_t ExpectedIndex = 0;
327  for (const WasmYAML::Signature &Sig : Section.Signatures) {
328  if (Sig.Index != ExpectedIndex) {
329  reportError("unexpected type index: " + Twine(Sig.Index));
330  return;
331  }
332  ++ExpectedIndex;
333  writeUint8(OS, Sig.Form);
334  encodeULEB128(Sig.ParamTypes.size(), OS);
335  for (auto ParamType : Sig.ParamTypes)
336  writeUint8(OS, ParamType);
337  encodeULEB128(Sig.ReturnTypes.size(), OS);
338  for (auto ReturnType : Sig.ReturnTypes)
339  writeUint8(OS, ReturnType);
340  }
341 }
342 
343 void WasmWriter::writeSectionContent(raw_ostream &OS,
344  WasmYAML::ImportSection &Section) {
345  encodeULEB128(Section.Imports.size(), OS);
346  for (const WasmYAML::Import &Import : Section.Imports) {
347  writeStringRef(Import.Module, OS);
348  writeStringRef(Import.Field, OS);
349  writeUint8(OS, Import.Kind);
350  switch (Import.Kind) {
352  encodeULEB128(Import.SigIndex, OS);
353  NumImportedFunctions++;
354  break;
356  writeUint8(OS, Import.GlobalImport.Type);
357  writeUint8(OS, Import.GlobalImport.Mutable);
358  NumImportedGlobals++;
359  break;
361  writeUint32(OS, Import.EventImport.Attribute);
362  writeUint32(OS, Import.EventImport.SigIndex);
363  NumImportedGlobals++;
364  break;
366  writeLimits(Import.Memory, OS);
367  break;
369  writeUint8(OS, Import.TableImport.ElemType);
370  writeLimits(Import.TableImport.TableLimits, OS);
371  break;
372  default:
373  reportError("unknown import type: " +Twine(Import.Kind));
374  return;
375  }
376  }
377 }
378 
379 void WasmWriter::writeSectionContent(raw_ostream &OS,
380  WasmYAML::FunctionSection &Section) {
381  encodeULEB128(Section.FunctionTypes.size(), OS);
382  for (uint32_t FuncType : Section.FunctionTypes)
383  encodeULEB128(FuncType, OS);
384 }
385 
386 void WasmWriter::writeSectionContent(raw_ostream &OS,
387  WasmYAML::ExportSection &Section) {
388  encodeULEB128(Section.Exports.size(), OS);
389  for (const WasmYAML::Export &Export : Section.Exports) {
390  writeStringRef(Export.Name, OS);
391  writeUint8(OS, Export.Kind);
392  encodeULEB128(Export.Index, OS);
393  }
394 }
395 
396 void WasmWriter::writeSectionContent(raw_ostream &OS,
397  WasmYAML::StartSection &Section) {
398  encodeULEB128(Section.StartFunction, OS);
399 }
400 
401 void WasmWriter::writeSectionContent(raw_ostream &OS,
402  WasmYAML::TableSection &Section) {
403  encodeULEB128(Section.Tables.size(), OS);
404  for (auto &Table : Section.Tables) {
405  writeUint8(OS, Table.ElemType);
406  writeLimits(Table.TableLimits, OS);
407  }
408 }
409 
410 void WasmWriter::writeSectionContent(raw_ostream &OS,
411  WasmYAML::MemorySection &Section) {
412  encodeULEB128(Section.Memories.size(), OS);
413  for (const WasmYAML::Limits &Mem : Section.Memories)
414  writeLimits(Mem, OS);
415 }
416 
417 void WasmWriter::writeSectionContent(raw_ostream &OS,
418  WasmYAML::GlobalSection &Section) {
419  encodeULEB128(Section.Globals.size(), OS);
420  uint32_t ExpectedIndex = NumImportedGlobals;
421  for (auto &Global : Section.Globals) {
422  if (Global.Index != ExpectedIndex) {
423  reportError("unexpected global index: " + Twine(Global.Index));
424  return;
425  }
426  ++ExpectedIndex;
427  writeUint8(OS, Global.Type);
428  writeUint8(OS, Global.Mutable);
429  writeInitExpr(OS, Global.InitExpr);
430  }
431 }
432 
433 void WasmWriter::writeSectionContent(raw_ostream &OS,
434  WasmYAML::EventSection &Section) {
435  encodeULEB128(Section.Events.size(), OS);
436  uint32_t ExpectedIndex = NumImportedEvents;
437  for (auto &Event : Section.Events) {
438  if (Event.Index != ExpectedIndex) {
439  reportError("unexpected event index: " + Twine(Event.Index));
440  return;
441  }
442  ++ExpectedIndex;
443  encodeULEB128(Event.Attribute, OS);
444  encodeULEB128(Event.SigIndex, OS);
445  }
446 }
447 
448 void WasmWriter::writeSectionContent(raw_ostream &OS,
449  WasmYAML::ElemSection &Section) {
450  encodeULEB128(Section.Segments.size(), OS);
451  for (auto &Segment : Section.Segments) {
452  encodeULEB128(Segment.TableIndex, OS);
453  writeInitExpr(OS, Segment.Offset);
454 
455  encodeULEB128(Segment.Functions.size(), OS);
456  for (auto &Function : Segment.Functions)
457  encodeULEB128(Function, OS);
458  }
459 }
460 
461 void WasmWriter::writeSectionContent(raw_ostream &OS,
462  WasmYAML::CodeSection &Section) {
463  encodeULEB128(Section.Functions.size(), OS);
464  uint32_t ExpectedIndex = NumImportedFunctions;
465  for (auto &Func : Section.Functions) {
466  std::string OutString;
467  raw_string_ostream StringStream(OutString);
468  if (Func.Index != ExpectedIndex) {
469  reportError("unexpected function index: " + Twine(Func.Index));
470  return;
471  }
472  ++ExpectedIndex;
473 
474  encodeULEB128(Func.Locals.size(), StringStream);
475  for (auto &LocalDecl : Func.Locals) {
476  encodeULEB128(LocalDecl.Count, StringStream);
477  writeUint8(StringStream, LocalDecl.Type);
478  }
479 
480  Func.Body.writeAsBinary(StringStream);
481 
482  // Write the section size followed by the content
483  StringStream.flush();
484  encodeULEB128(OutString.size(), OS);
485  OS << OutString;
486  }
487 }
488 
489 void WasmWriter::writeSectionContent(raw_ostream &OS,
490  WasmYAML::DataSection &Section) {
491  encodeULEB128(Section.Segments.size(), OS);
492  for (auto &Segment : Section.Segments) {
493  encodeULEB128(Segment.InitFlags, OS);
494  if (Segment.InitFlags & wasm::WASM_SEGMENT_HAS_MEMINDEX)
495  encodeULEB128(Segment.MemoryIndex, OS);
496  if ((Segment.InitFlags & wasm::WASM_SEGMENT_IS_PASSIVE) == 0)
497  writeInitExpr(OS, Segment.Offset);
498  encodeULEB128(Segment.Content.binary_size(), OS);
499  Segment.Content.writeAsBinary(OS);
500  }
501 }
502 
503 void WasmWriter::writeSectionContent(raw_ostream &OS,
504  WasmYAML::DataCountSection &Section) {
505  encodeULEB128(Section.Count, OS);
506 }
507 
508 void WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
509  uint32_t SectionIndex) {
510  switch (Sec.Type) {
511  case wasm::WASM_SEC_CODE:
512  writeStringRef("reloc.CODE", OS);
513  break;
514  case wasm::WASM_SEC_DATA:
515  writeStringRef("reloc.DATA", OS);
516  break;
517  case wasm::WASM_SEC_CUSTOM: {
518  auto *CustomSection = cast<WasmYAML::CustomSection>(&Sec);
519  writeStringRef(("reloc." + CustomSection->Name).str(), OS);
520  break;
521  }
522  default:
523  llvm_unreachable("not yet implemented");
524  }
525 
526  encodeULEB128(SectionIndex, OS);
527  encodeULEB128(Sec.Relocations.size(), OS);
528 
529  for (auto Reloc : Sec.Relocations) {
530  writeUint8(OS, Reloc.Type);
531  encodeULEB128(Reloc.Offset, OS);
532  encodeULEB128(Reloc.Index, OS);
533  switch (Reloc.Type) {
534  case wasm::R_WASM_MEMORY_ADDR_LEB:
535  case wasm::R_WASM_MEMORY_ADDR_SLEB:
536  case wasm::R_WASM_MEMORY_ADDR_I32:
537  case wasm::R_WASM_FUNCTION_OFFSET_I32:
538  case wasm::R_WASM_SECTION_OFFSET_I32:
539  encodeULEB128(Reloc.Addend, OS);
540  }
541  }
542 }
543 
544 bool WasmWriter::writeWasm(raw_ostream &OS) {
545  // Write headers
547  writeUint32(OS, Obj.Header.Version);
548 
549  // Write each section
551  for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
552  StringRef SecName = "";
553  if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get()))
554  SecName = S->Name;
555  if (!Checker.isValidSectionOrder(Sec->Type, SecName)) {
556  reportError("out of order section type: " + Twine(Sec->Type));
557  return false;
558  }
559  encodeULEB128(Sec->Type, OS);
560  std::string OutString;
561  raw_string_ostream StringStream(OutString);
562  if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get()))
563  writeSectionContent(StringStream, *S);
564  else if (auto S = dyn_cast<WasmYAML::TypeSection>(Sec.get()))
565  writeSectionContent(StringStream, *S);
566  else if (auto S = dyn_cast<WasmYAML::ImportSection>(Sec.get()))
567  writeSectionContent(StringStream, *S);
568  else if (auto S = dyn_cast<WasmYAML::FunctionSection>(Sec.get()))
569  writeSectionContent(StringStream, *S);
570  else if (auto S = dyn_cast<WasmYAML::TableSection>(Sec.get()))
571  writeSectionContent(StringStream, *S);
572  else if (auto S = dyn_cast<WasmYAML::MemorySection>(Sec.get()))
573  writeSectionContent(StringStream, *S);
574  else if (auto S = dyn_cast<WasmYAML::GlobalSection>(Sec.get()))
575  writeSectionContent(StringStream, *S);
576  else if (auto S = dyn_cast<WasmYAML::EventSection>(Sec.get()))
577  writeSectionContent(StringStream, *S);
578  else if (auto S = dyn_cast<WasmYAML::ExportSection>(Sec.get()))
579  writeSectionContent(StringStream, *S);
580  else if (auto S = dyn_cast<WasmYAML::StartSection>(Sec.get()))
581  writeSectionContent(StringStream, *S);
582  else if (auto S = dyn_cast<WasmYAML::ElemSection>(Sec.get()))
583  writeSectionContent(StringStream, *S);
584  else if (auto S = dyn_cast<WasmYAML::CodeSection>(Sec.get()))
585  writeSectionContent(StringStream, *S);
586  else if (auto S = dyn_cast<WasmYAML::DataSection>(Sec.get()))
587  writeSectionContent(StringStream, *S);
588  else if (auto S = dyn_cast<WasmYAML::DataCountSection>(Sec.get()))
589  writeSectionContent(StringStream, *S);
590  else
591  reportError("unknown section type: " + Twine(Sec->Type));
592 
593  if (HasError)
594  return false;
595 
596  StringStream.flush();
597 
598  // Write the section size followed by the content
599  encodeULEB128(OutString.size(), OS);
600  OS << OutString;
601  }
602 
603  // write reloc sections for any section that have relocations
604  uint32_t SectionIndex = 0;
605  for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
606  if (Sec->Relocations.empty()) {
607  SectionIndex++;
608  continue;
609  }
610 
612  std::string OutString;
613  raw_string_ostream StringStream(OutString);
614  writeRelocSection(StringStream, *Sec, SectionIndex++);
615  StringStream.flush();
616 
617  encodeULEB128(OutString.size(), OS);
618  OS << OutString;
619  }
620 
621  return true;
622 }
623 
624 namespace llvm {
625 namespace yaml {
626 
628  WasmWriter Writer(Doc, EH);
629  return Writer.writeWasm(Out);
630 }
631 
632 } // namespace yaml
633 } // namespace llvm
static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS)
std::vector< InitFunction > InitFunctions
Definition: WasmYAML.h:234
uint64_t CallInst * C
std::vector< Comdat > Comdats
Definition: WasmYAML.h:235
std::vector< Relocation > Relocations
Definition: WasmYAML.h:182
std::vector< Limits > Memories
Definition: WasmYAML.h:309
std::vector< Signature > Signatures
Definition: WasmYAML.h:269
This class represents lattice values for constants.
Definition: AllocatorList.h:23
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLExtras.h:104
void write32le(void *P, uint32_t V)
Definition: Endian.h:418
std::string Name
std::vector< Import > Imports
Definition: WasmYAML.h:279
Export information to summary.
std::vector< ProducerEntry > Languages
Definition: WasmYAML.h:246
const unsigned WASM_SYMBOL_UNDEFINED
Definition: Wasm.h:331
std::vector< ValueType > ReturnTypes
Definition: WasmYAML.h:148
std::vector< SegmentInfo > SegmentInfos
Definition: WasmYAML.h:233
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
std::vector< SymbolInfo > SymbolTable
Definition: WasmYAML.h:232
static int writeUint32(raw_ostream &OS, uint32_t Value)
Definition: WasmEmitter.cpp:97
bool isValidSectionOrder(unsigned ID, StringRef CustomSectionName="")
std::vector< Function > Functions
Definition: WasmYAML.h:369
static int writeUint8(raw_ostream &OS, uint8_t Value)
union llvm::wasm::WasmInitExpr::@151 Value
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:144
yaml::Hex32 Initial
Definition: WasmYAML.h:49
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
uint32_t Attribute
Definition: WasmYAML.h:79
Import information from summary.
yaml::Hex32 Maximum
Definition: WasmYAML.h:50
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void writeAsBinary(raw_ostream &OS) const
Write the contents (regardless of whether it is binary or a hex string) as binary to the given raw_os...
Definition: YAML.cpp:40
std::vector< Export > Exports
Definition: WasmYAML.h:339
std::vector< ProducerEntry > Tools
Definition: WasmYAML.h:247
std::vector< uint32_t > FunctionTypes
Definition: WasmYAML.h:289
static int writeStringRef(const StringRef &Str, raw_ostream &OS)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
raw_ostream & write(unsigned char C)
const char WasmMagic[]
Definition: Wasm.h:25
std::vector< ProducerEntry > SDKs
Definition: WasmYAML.h:248
static Error reportError(StringRef Message)
const unsigned WASM_SYMBOL_EXPLICIT_NAME
Definition: Wasm.h:333
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
Definition: LEB128.h:23
Common declarations for yaml2obj.
TableType ElemType
Definition: WasmYAML.h:54
std::vector< Table > Tables
Definition: WasmYAML.h:299
LimitFlags Flags
Definition: WasmYAML.h:48
std::vector< ElemSegment > Segments
Definition: WasmYAML.h:359
std::vector< FeatureEntry > Features
Definition: WasmYAML.h:259
static int writeUint64(raw_ostream &OS, uint64_t Value)
Definition: WasmEmitter.cpp:90
std::vector< Event > Events
Definition: WasmYAML.h:329
void write64le(void *P, uint64_t V)
Definition: Endian.h:419
std::vector< DataSegment > Segments
Definition: WasmYAML.h:379
wasm::WasmDataReference DataRef
Definition: WasmYAML.h:158
std::vector< ValueType > ParamTypes
Definition: WasmYAML.h:147
yaml::BinaryRef Payload
Definition: WasmYAML.h:194
std::vector< NameEntry > FunctionNames
Definition: WasmYAML.h:220
std::vector< Global > Globals
Definition: WasmYAML.h:319
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:503
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
SignatureForm Form
Definition: WasmYAML.h:146
bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH)