llvm.org GIT mirror llvm / 9f474de
[WebAssembly] Use uint8_t for single byte values to match the spec The original BinaryEncoding.md document used to specify that these values were `varint7`, but the official spec lists them explicitly as single byte values and not LEB. A similar change for wabt is in flight: https://github.com/WebAssembly/wabt/pull/782 Differential Revision: https://reviews.llvm.org/D43921 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326454 91177308-0d34-0410-b5e6-96231b3b80d8 Sam Clegg 1 year, 7 months ago
7 changed file(s) with 75 addition(s) and 87 deletion(s). Raw diff Collapse all Expand all
3232 };
3333
3434 struct WasmSignature {
35 std::vector ParamTypes;
36 int32_t ReturnType;
35 std::vector ParamTypes;
36 uint8_t ReturnType;
3737 };
3838
3939 struct WasmExport {
4040 StringRef Name;
41 uint32_t Kind;
41 uint8_t Kind;
4242 uint32_t Index;
4343 };
4444
4545 struct WasmLimits {
46 uint32_t Flags;
46 uint8_t Flags;
4747 uint32_t Initial;
4848 uint32_t Maximum;
4949 };
5050
5151 struct WasmTable {
52 int32_t ElemType;
52 uint8_t ElemType;
5353 WasmLimits Limits;
5454 };
5555
6565 };
6666
6767 struct WasmGlobalType {
68 int32_t Type;
68 uint8_t Type;
6969 bool Mutable;
7070 };
7171
7878 struct WasmImport {
7979 StringRef Module;
8080 StringRef Field;
81 uint32_t Kind;
81 uint8_t Kind;
8282 union {
8383 uint32_t SigIndex;
8484 WasmGlobalType Global;
8888 };
8989
9090 struct WasmLocalDecl {
91 int32_t Type;
91 uint8_t Type;
9292 uint32_t Count;
9393 };
9494
127127 };
128128
129129 struct WasmRelocation {
130 uint32_t Type; // The type of the relocation.
130 uint8_t Type; // The type of the relocation.
131131 uint32_t Index; // Index into either symbol or type index space.
132132 uint64_t Offset; // Offset from the start of the section.
133133 int64_t Addend; // A value to add to the symbol.
140140
141141 struct WasmSymbolInfo {
142142 StringRef Name;
143 uint32_t Kind;
143 uint8_t Kind;
144144 uint32_t Flags;
145145 union {
146146 // For function or global symbols, the index in function of global index
177177 };
178178
179179 // Type immediate encodings used in various contexts.
180 enum {
181 WASM_TYPE_I32 = -0x01,
182 WASM_TYPE_I64 = -0x02,
183 WASM_TYPE_F32 = -0x03,
184 WASM_TYPE_F64 = -0x04,
185 WASM_TYPE_ANYFUNC = -0x10,
186 WASM_TYPE_FUNC = -0x20,
187 WASM_TYPE_NORESULT = -0x40, // for blocks with no result values
180 enum : uint8_t {
181 WASM_TYPE_I32 = 0x7F,
182 WASM_TYPE_I64 = 0x7E,
183 WASM_TYPE_F32 = 0x7D,
184 WASM_TYPE_F64 = 0x7C,
185 WASM_TYPE_ANYFUNC = 0x70,
186 WASM_TYPE_FUNC = 0x60,
187 WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
188188 };
189189
190190 // Kinds of externals (for imports and exports).
191 enum : unsigned {
191 enum : uint8_t {
192192 WASM_EXTERNAL_FUNCTION = 0x0,
193193 WASM_EXTERNAL_TABLE = 0x1,
194194 WASM_EXTERNAL_MEMORY = 0x2,
238238 };
239239
240240 // Kind codes used in the custom "linking" section in the WASM_SYMBOL_TABLE
241 enum WasmSymbolType : unsigned {
241 enum WasmSymbolType : uint8_t {
242242 WASM_SYMBOL_TYPE_FUNCTION = 0x0,
243243 WASM_SYMBOL_TYPE_DATA = 0x1,
244244 WASM_SYMBOL_TYPE_GLOBAL = 0x2,
256256
257257 #define WASM_RELOC(name, value) name = value,
258258
259 enum : unsigned {
259 enum : uint8_t {
260260 #include "WasmRelocs.def"
261261 };
262262
2727 namespace WasmYAML {
2828
2929 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionType)
30 LLVM_YAML_STRONG_TYPEDEF(int32_t, ValueType)
31 LLVM_YAML_STRONG_TYPEDEF(int32_t, TableType)
32 LLVM_YAML_STRONG_TYPEDEF(int32_t, SignatureForm)
33 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportKind)
30 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ValueType)
31 LLVM_YAML_STRONG_TYPEDEF(uint8_t, TableType)
32 LLVM_YAML_STRONG_TYPEDEF(uint8_t, SignatureForm)
33 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ExportKind)
3434 LLVM_YAML_STRONG_TYPEDEF(uint32_t, Opcode)
35 LLVM_YAML_STRONG_TYPEDEF(uint32_t, RelocType)
35 LLVM_YAML_STRONG_TYPEDEF(uint8_t, RelocType)
3636 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolFlags)
37 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SymbolKind)
37 LLVM_YAML_STRONG_TYPEDEF(uint8_t, SymbolKind)
3838 LLVM_YAML_STRONG_TYPEDEF(uint32_t, SegmentFlags)
39 LLVM_YAML_STRONG_TYPEDEF(uint32_t, LimitFlags)
40 LLVM_YAML_STRONG_TYPEDEF(uint32_t, ComdatKind)
39 LLVM_YAML_STRONG_TYPEDEF(uint8_t, LimitFlags)
40 LLVM_YAML_STRONG_TYPEDEF(uint8_t, ComdatKind)
4141
4242 struct FileHeader {
4343 yaml::Hex32 Version;
257257 }
258258
259259 void writeValueType(wasm::ValType Ty) {
260 encodeSLEB128(int32_t(Ty), getStream());
260 write8(static_cast(Ty));
261261 }
262262
263263 void writeTypeSection(ArrayRef FunctionTypes);
299299 "Only custom sections can have names");
300300
301301 DEBUG(dbgs() << "startSection " << SectionId << ": " << Name << "\n");
302 encodeULEB128(SectionId, getStream());
302 write8(SectionId);
303303
304304 Section.SizeOffset = getStream().tell();
305305
624624 RelEntry.FixupSection->getSectionOffset();
625625 uint32_t Index = getRelocationIndexValue(RelEntry);
626626
627 encodeULEB128(RelEntry.Type, Stream);
627 write8(RelEntry.Type);
628628 encodeULEB128(Offset, Stream);
629629 encodeULEB128(Index, Stream);
630630 if (RelEntry.hasAddend())
643643 encodeULEB128(FunctionTypes.size(), getStream());
644644
645645 for (const WasmFunctionType &FuncTy : FunctionTypes) {
646 encodeSLEB128(wasm::WASM_TYPE_FUNC, getStream());
646 write8(wasm::WASM_TYPE_FUNC);
647647 encodeULEB128(FuncTy.Params.size(), getStream());
648648 for (wasm::ValType Ty : FuncTy.Params)
649649 writeValueType(Ty);
670670 for (const wasm::WasmImport &Import : Imports) {
671671 writeString(Import.Module);
672672 writeString(Import.Field);
673 encodeULEB128(Import.Kind, getStream());
673 write8(Import.Kind);
674674
675675 switch (Import.Kind) {
676676 case wasm::WASM_EXTERNAL_FUNCTION:
677677 encodeULEB128(Import.SigIndex, getStream());
678678 break;
679679 case wasm::WASM_EXTERNAL_GLOBAL:
680 encodeSLEB128(Import.Global.Type, getStream());
681 encodeULEB128(uint32_t(Import.Global.Mutable), getStream());
680 write8(Import.Global.Type);
681 write8(Import.Global.Mutable ? 1 : 0);
682682 break;
683683 case wasm::WASM_EXTERNAL_MEMORY:
684684 encodeULEB128(0, getStream()); // flags
685685 encodeULEB128(NumPages, getStream()); // initial
686686 break;
687687 case wasm::WASM_EXTERNAL_TABLE:
688 encodeSLEB128(Import.Table.ElemType, getStream());
688 write8(Import.Table.ElemType);
689689 encodeULEB128(0, getStream()); // flags
690690 encodeULEB128(NumElements, getStream()); // initial
691691 break;
741741 encodeULEB128(Exports.size(), getStream());
742742 for (const wasm::WasmExport &Export : Exports) {
743743 writeString(Export.Name);
744 encodeSLEB128(Export.Kind, getStream());
744 write8(Export.Kind);
745745 encodeULEB128(Export.Index, getStream());
746746 }
747747
9898 return result;
9999 }
100100
101 static int8_t readVarint7(const uint8_t *&Ptr) {
102 int64_t result = readLEB128(Ptr);
103 assert(result <= VARINT7_MAX && result >= VARINT7_MIN);
104 return result;
105 }
106
107 static uint8_t readVaruint7(const uint8_t *&Ptr) {
108 uint64_t result = readULEB128(Ptr);
109 assert(result <= VARUINT7_MAX);
110 return result;
111 }
112
113101 static int32_t readVarint32(const uint8_t *&Ptr) {
114102 int64_t result = readLEB128(Ptr);
115103 assert(result <= INT32_MAX && result >= INT32_MIN);
173161
174162 static wasm::WasmTable readTable(const uint8_t *&Ptr) {
175163 wasm::WasmTable Table;
176 Table.ElemType = readVarint7(Ptr);
164 Table.ElemType = readUint8(Ptr);
177165 Table.Limits = readLimits(Ptr);
178166 return Table;
179167 }
181169 static Error readSection(WasmSection &Section, const uint8_t *&Ptr,
182170 const uint8_t *Start, const uint8_t *Eof) {
183171 Section.Offset = Ptr - Start;
184 Section.Type = readVaruint7(Ptr);
172 Section.Type = readUint8(Ptr);
185173 uint32_t Size = readVaruint32(Ptr);
186174 if (Size == 0)
187175 return make_error("Zero length section",
273261 }
274262
275263 while (Ptr < End) {
276 uint8_t Type = readVarint7(Ptr);
264 uint8_t Type = readUint8(Ptr);
277265 uint32_t Size = readVaruint32(Ptr);
278266 const uint8_t *SubSectionEnd = Ptr + Size;
279267 switch (Type) {
323311 }
324312
325313 while (Ptr < End) {
326 uint8_t Type = readVarint7(Ptr);
314 uint8_t Type = readUint8(Ptr);
327315 uint32_t Size = readVaruint32(Ptr);
328316 const uint8_t *SubSectionEnd = Ptr + Size;
329317 switch (Type) {
547535
548536 Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr,
549537 const uint8_t *End) {
550 uint8_t SectionCode = readVarint7(Ptr);
538 uint8_t SectionCode = readUint8(Ptr);
551539 WasmSection* Section = nullptr;
552540 if (SectionCode == wasm::WASM_SEC_CUSTOM) {
553541 StringRef Name = readString(Ptr);
612600 while (Count--) {
613601 wasm::WasmSignature Sig;
614602 Sig.ReturnType = wasm::WASM_TYPE_NORESULT;
615 int8_t Form = readVarint7(Ptr);
603 uint8_t Form = readUint8(Ptr);
616604 if (Form != wasm::WASM_TYPE_FUNC) {
617605 return make_error("Invalid signature type",
618606 object_error::parse_failed);
620608 uint32_t ParamCount = readVaruint32(Ptr);
621609 Sig.ParamTypes.reserve(ParamCount);
622610 while (ParamCount--) {
623 uint32_t ParamType = readVarint7(Ptr);
611 uint32_t ParamType = readUint8(Ptr);
624612 Sig.ParamTypes.push_back(ParamType);
625613 }
626614 uint32_t ReturnCount = readVaruint32(Ptr);
629617 return make_error(
630618 "Multiple return types not supported", object_error::parse_failed);
631619 }
632 Sig.ReturnType = readVarint7(Ptr);
620 Sig.ReturnType = readUint8(Ptr);
633621 }
634622 Signatures.push_back(Sig);
635623 }
654642 break;
655643 case wasm::WASM_EXTERNAL_GLOBAL:
656644 NumImportedGlobals++;
657 Im.Global.Type = readVarint7(Ptr);
645 Im.Global.Type = readUint8(Ptr);
658646 Im.Global.Mutable = readVaruint1(Ptr);
659647 break;
660648 case wasm::WASM_EXTERNAL_MEMORY:
725713 while (Count--) {
726714 wasm::WasmGlobal Global;
727715 Global.Index = NumImportedGlobals + Globals.size();
728 Global.Type.Type = readVarint7(Ptr);
716 Global.Type.Type = readUint8(Ptr);
729717 Global.Type.Mutable = readVaruint1(Ptr);
730718 if (Error Err = readInitExpr(Global.InitExpr, Ptr))
731719 return Err;
833821 while (NumLocalDecls--) {
834822 wasm::WasmLocalDecl Decl;
835823 Decl.Count = readVaruint32(Ptr);
836 Decl.Type = readVarint7(Ptr);
824 Decl.Type = readUint8(Ptr);
837825 Function.Locals.push_back(Decl);
838826 }
839827
3030 : MCTargetStreamer(S) {}
3131
3232 void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
33 Streamer.EmitSLEB128IntValue(int32_t(Type));
33 Streamer.EmitIntValue(uint8_t(Type), 1);
3434 }
3535
3636 WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
9494 // here; this method is precisely there for fetching the signatures of known
9595 // Clang-provided symbols.
9696 if (strcmp(Name, "__stack_pointer") == 0) {
97 wasm::ValType iPTR =
98 Subtarget.hasAddr64() ? wasm::ValType::I64 : wasm::ValType::I32;
9997 WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
100 WasmSym->setGlobalType(wasm::WasmGlobalType{int32_t(iPTR), true});
98 WasmSym->setGlobalType(wasm::WasmGlobalType{
99 Subtarget.hasAddr64() ? wasm::WASM_TYPE_I64 : wasm::WASM_TYPE_I32,
100 true});
101101 return WasmSym;
102102 }
103103
7777 }
7878
7979 static int writeLimits(const WasmYAML::Limits &Lim, raw_ostream &OS) {
80 encodeULEB128(Lim.Flags, OS);
80 writeUint8(OS, Lim.Flags);
8181 encodeULEB128(Lim.Initial, OS);
8282 if (Lim.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
8383 encodeULEB128(Lim.Maximum, OS);
137137
138138 // SYMBOL_TABLE subsection
139139 if (Section.SymbolTable.size()) {
140 encodeULEB128(wasm::WASM_SYMBOL_TABLE, OS);
140 writeUint8(OS, wasm::WASM_SYMBOL_TABLE);
141141
142142 encodeULEB128(Section.SymbolTable.size(), SubSection.GetStream());
143143 #ifndef NDEBUG
145145 #endif
146146 for (const WasmYAML::SymbolInfo &Info : Section.SymbolTable) {
147147 assert(Info.Index == SymbolIndex++);
148 encodeULEB128(Info.Kind, SubSection.GetStream());
148 writeUint8(SubSection.GetStream(), Info.Kind);
149149 encodeULEB128(Info.Flags, SubSection.GetStream());
150150 switch (Info.Kind) {
151151 case wasm::WASM_SYMBOL_TYPE_FUNCTION:
172172
173173 // SEGMENT_NAMES subsection
174174 if (Section.SegmentInfos.size()) {
175 encodeULEB128(wasm::WASM_SEGMENT_INFO, OS);
175 writeUint8(OS, wasm::WASM_SEGMENT_INFO);
176176 encodeULEB128(Section.SegmentInfos.size(), SubSection.GetStream());
177177 for (const WasmYAML::SegmentInfo &SegmentInfo : Section.SegmentInfos) {
178178 writeStringRef(SegmentInfo.Name, SubSection.GetStream());
184184
185185 // INIT_FUNCS subsection
186186 if (Section.InitFunctions.size()) {
187 encodeULEB128(wasm::WASM_INIT_FUNCS, OS);
187 writeUint8(OS, wasm::WASM_INIT_FUNCS);
188188 encodeULEB128(Section.InitFunctions.size(), SubSection.GetStream());
189189 for (const WasmYAML::InitFunction &Func : Section.InitFunctions) {
190190 encodeULEB128(Func.Priority, SubSection.GetStream());
195195
196196 // COMDAT_INFO subsection
197197 if (Section.Comdats.size()) {
198 encodeULEB128(wasm::WASM_COMDAT_INFO, OS);
198 writeUint8(OS, wasm::WASM_COMDAT_INFO);
199199 encodeULEB128(Section.Comdats.size(), SubSection.GetStream());
200200 for (const auto &C : Section.Comdats) {
201201 writeStringRef(C.Name, SubSection.GetStream());
202202 encodeULEB128(0, SubSection.GetStream()); // flags for future use
203203 encodeULEB128(C.Entries.size(), SubSection.GetStream());
204204 for (const WasmYAML::ComdatEntry &Entry : C.Entries) {
205 encodeULEB128(Entry.Kind, SubSection.GetStream());
205 writeUint8(SubSection.GetStream(), Entry.Kind);
206206 encodeULEB128(Entry.Index, SubSection.GetStream());
207207 }
208208 }
215215 int WasmWriter::writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section) {
216216 writeStringRef(Section.Name, OS);
217217 if (Section.FunctionNames.size()) {
218 encodeULEB128(wasm::WASM_NAMES_FUNCTION, OS);
218 writeUint8(OS, wasm::WASM_NAMES_FUNCTION);
219219
220220 SubSectionWriter SubSection(OS);
221221
254254 return 1;
255255 }
256256 ++ExpectedIndex;
257 encodeSLEB128(Sig.Form, OS);
257 writeUint8(OS, Sig.Form);
258258 encodeULEB128(Sig.ParamTypes.size(), OS);
259259 for (auto ParamType : Sig.ParamTypes)
260 encodeSLEB128(ParamType, OS);
260 writeUint8(OS, ParamType);
261261 if (Sig.ReturnType == wasm::WASM_TYPE_NORESULT) {
262 encodeSLEB128(0, OS);
262 encodeULEB128(0, OS);
263263 } else {
264264 encodeULEB128(1, OS);
265 encodeSLEB128(Sig.ReturnType, OS);
265 writeUint8(OS, Sig.ReturnType);
266266 }
267267 }
268268 return 0;
274274 for (const WasmYAML::Import &Import : Section.Imports) {
275275 writeStringRef(Import.Module, OS);
276276 writeStringRef(Import.Field, OS);
277 encodeULEB128(Import.Kind, OS);
277 writeUint8(OS, Import.Kind);
278278 switch (Import.Kind) {
279279 case wasm::WASM_EXTERNAL_FUNCTION:
280280 encodeULEB128(Import.SigIndex, OS);
281281 NumImportedFunctions++;
282282 break;
283283 case wasm::WASM_EXTERNAL_GLOBAL:
284 encodeSLEB128(Import.GlobalImport.Type, OS);
284 writeUint8(OS, Import.GlobalImport.Type);
285285 writeUint8(OS, Import.GlobalImport.Mutable);
286286 NumImportedGlobals++;
287287 break;
289289 writeLimits(Import.Memory, OS);
290290 break;
291291 case wasm::WASM_EXTERNAL_TABLE:
292 encodeSLEB128(Import.TableImport.ElemType, OS);
292 writeUint8(OS,Import.TableImport.ElemType);
293293 writeLimits(Import.TableImport.TableLimits, OS);
294294 break;
295295 default:
314314 encodeULEB128(Section.Exports.size(), OS);
315315 for (const WasmYAML::Export &Export : Section.Exports) {
316316 writeStringRef(Export.Name, OS);
317 encodeULEB128(Export.Kind, OS);
317 writeUint8(OS, Export.Kind);
318318 encodeULEB128(Export.Index, OS);
319319 }
320320 return 0;
330330 WasmYAML::TableSection &Section) {
331331 encodeULEB128(Section.Tables.size(), OS);
332332 for (auto &Table : Section.Tables) {
333 encodeSLEB128(Table.ElemType, OS);
333 writeUint8(OS, Table.ElemType);
334334 writeLimits(Table.TableLimits, OS);
335335 }
336336 return 0;
355355 return 1;
356356 }
357357 ++ExpectedIndex;
358 encodeSLEB128(Global.Type, OS);
358 writeUint8(OS, Global.Type);
359359 writeUint8(OS, Global.Mutable);
360360 writeInitExpr(Global.InitExpr, OS);
361361 }
393393 encodeULEB128(Func.Locals.size(), StringStream);
394394 for (auto &LocalDecl : Func.Locals) {
395395 encodeULEB128(LocalDecl.Count, StringStream);
396 encodeSLEB128(LocalDecl.Type, StringStream);
396 writeUint8(StringStream, LocalDecl.Type);
397397 }
398398
399399 Func.Body.writeAsBinary(StringStream);
434434 }
435435
436436 writeStringRef(Name, OS);
437 encodeULEB128(Sec.Type, OS);
437 writeUint8(OS, Sec.Type);
438438 encodeULEB128(Sec.Relocations.size(), OS);
439439
440440 for (auto Reloc: Sec.Relocations) {
441 encodeULEB128(Reloc.Type, OS);
441 writeUint8(OS, Reloc.Type);
442442 encodeULEB128(Reloc.Offset, OS);
443443 encodeULEB128(Reloc.Index, OS);
444444 switch (Reloc.Type) {
524524 if (Sec->Relocations.empty())
525525 continue;
526526
527 encodeULEB128(wasm::WASM_SEC_CUSTOM, OS);
527 writeUint8(OS, wasm::WASM_SEC_CUSTOM);
528528 std::string OutString;
529529 raw_string_ostream StringStream(OutString);
530530 writeRelocSection(StringStream, *Sec);