1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00

[WebAssembly] Explicitly specify function/global index space in YAML

These indexes are useful because they are not always zero based and
functions and globals are referenced elsewhere by their index.

This matches what we already do for the type index space.

Differential Revision: https://reviews.llvm.org/D41877

llvm-svn: 322121
This commit is contained in:
Sam Clegg 2018-01-09 21:38:53 +00:00
parent 49faf0a1ac
commit 9ebc8a13dc
23 changed files with 168 additions and 75 deletions

View File

@ -66,6 +66,7 @@ struct WasmInitExpr {
};
struct WasmGlobal {
uint32_t Index;
int32_t Type;
bool Mutable;
WasmInitExpr InitExpr;
@ -89,6 +90,7 @@ struct WasmLocalDecl {
};
struct WasmFunction {
uint32_t Index;
std::vector<WasmLocalDecl> Locals;
ArrayRef<uint8_t> Body;
uint32_t CodeSectionOffset;

View File

@ -66,6 +66,7 @@ struct ElemSegment {
};
struct Global {
uint32_t Index;
ValueType Type;
bool Mutable;
wasm::WasmInitExpr InitExpr;
@ -89,6 +90,7 @@ struct LocalDecl {
};
struct Function {
uint32_t Index;
std::vector<LocalDecl> Locals;
yaml::BinaryRef Body;
};

View File

@ -632,6 +632,7 @@ Error WasmObjectFile::parseGlobalSection(const uint8_t *Ptr, const uint8_t *End)
Globals.reserve(Count);
while (Count--) {
wasm::WasmGlobal Global;
Global.Index = NumImportedGlobals + Globals.size();
Global.Type = readVarint7(Ptr);
Global.Mutable = readVaruint1(Ptr);
if (Error Err = readInitExpr(Global.InitExpr, Ptr))
@ -706,6 +707,7 @@ Error WasmObjectFile::parseCodeSection(const uint8_t *Ptr, const uint8_t *End) {
uint32_t Size = readVaruint32(Ptr);
const uint8_t *FunctionEnd = Ptr + Size;
Function.Index = NumImportedFunctions + Functions.size();
Function.CodeSectionOffset = FunctionStart - CodeSectionStart;
Function.Size = FunctionEnd - FunctionStart;
@ -858,7 +860,7 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol& Sym) const {
case WasmSymbol::SymbolType::GLOBAL_EXPORT: {
uint32_t GlobalIndex = Sym.ElementIndex - NumImportedGlobals;
assert(GlobalIndex < Globals.size());
const wasm::WasmGlobal& Global = Globals[GlobalIndex];
const wasm::WasmGlobal &Global = Globals[GlobalIndex];
// WasmSymbols correspond only to I32_CONST globals
assert(Global.InitExpr.Opcode == wasm::WASM_OPCODE_I32_CONST);
return Global.InitExpr.Value.Int32;

View File

@ -236,7 +236,7 @@ void ScalarEnumerationTraits<WasmYAML::SectionType>::enumeration(
void MappingTraits<WasmYAML::Signature>::mapping(
IO &IO, WasmYAML::Signature &Signature) {
IO.mapOptional("Index", Signature.Index);
IO.mapRequired("Index", Signature.Index);
IO.mapRequired("ReturnType", Signature.ReturnType);
IO.mapRequired("ParamTypes", Signature.ParamTypes);
}
@ -248,6 +248,7 @@ void MappingTraits<WasmYAML::Table>::mapping(IO &IO, WasmYAML::Table &Table) {
void MappingTraits<WasmYAML::Function>::mapping(IO &IO,
WasmYAML::Function &Function) {
IO.mapRequired("Index", Function.Index);
IO.mapRequired("Locals", Function.Locals);
IO.mapRequired("Body", Function.Body);
}
@ -323,6 +324,7 @@ void MappingTraits<WasmYAML::Export>::mapping(IO &IO,
void MappingTraits<WasmYAML::Global>::mapping(IO &IO,
WasmYAML::Global &Global) {
IO.mapRequired("Index", Global.Index);
IO.mapRequired("Type", Global.Type);
IO.mapRequired("Mutable", Global.Mutable);
IO.mapRequired("InitExpr", Global.InitExpr);

View File

@ -9,22 +9,26 @@
; CHECK: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 4
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 8
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST

View File

@ -9,22 +9,26 @@
; CHECK: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 8
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 16
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST

View File

@ -55,7 +55,8 @@ declare void @func3()
; CHECK-NEXT: FunctionTypes: [ 0, 1, 0, 1 ]
; CHECK-NEXT: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
@ -110,13 +111,17 @@ declare void @func3()
; CHECK-NEXT: Index: 1
; CHECK-NEXT: Offset: 0x00000045
; CHECK-NEXT: Functions:
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 5
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 1080808080000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 6
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 0240418080808000410041FFFFFFFF7F1081808080000D000F0B00000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 7
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 1082808080000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 8
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 0240418180808000410041FFFFFFFF7F1081808080000D000F0B00000B
; CHECK-NEXT: - Type: DATA
; CHECK-NEXT: Segments:

View File

@ -9,22 +9,26 @@
; CHECK: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 0
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 0
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 6
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 16
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST

View File

@ -76,17 +76,20 @@ entry:
; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
; CHECK-NEXT: - Type: GLOBAL
; CHECK-NEXT: Globals:
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 8
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
; CHECK-NEXT: Value: 16
; CHECK-NEXT: - Type: I32
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Type: I32
; CHECK-NEXT: Mutable: false
; CHECK-NEXT: InitExpr:
; CHECK-NEXT: Opcode: I32_CONST
@ -150,15 +153,20 @@ entry:
; CHECK-NEXT: Index: 0
; CHECK-NEXT: Offset: 0x00000037
; CHECK-NEXT: Functions:
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 1
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 41000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 2
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 1081808080000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 3
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 1080808080000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 4
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 410028028880808000118080808000000B
; CHECK-NEXT: - Locals:
; CHECK-NEXT: - Index: 5
; CHECK-NEXT: Locals:
; CHECK-NEXT: Body: 410028029080808000118080808000000B
; CHECK-NEXT: - Type: DATA
; CHECK-NEXT: Relocations:

View File

@ -5,10 +5,12 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: F32
- Index: 0
ReturnType: F32
ParamTypes:
- I32
- ReturnType: NORESULT
- Index: 1
ReturnType: NORESULT
ParamTypes:
- I32
- I64
@ -25,11 +27,13 @@ Sections:
Index: 1
Offset: 0x00000025
Functions:
- Locals:
- Index: 0
Locals:
- Type: I32
Count: 3
Body: 418080808000210020002101200111808080800000210220020F0B
- Locals:
- Index: 1
Locals:
- Type: I32
Count: 1
Body: 108180808000210020000F0B
@ -58,11 +62,13 @@ Sections:
# CHECK: Index: 1
# CHECK: Offset: 0x00000025
# CHECK: Functions:
# CHECK: - Locals:
# CHECK: - Index: 0
# CHECK: Locals:
# CHECK: - Type: I32
# CHECK: Count: 3
# CHECK: Body: 418080808000210020002101200111808080800000210220020F0B
# CHECK: - Locals:
# CHECK: - Index: 1
# CHECK: Locals:
# CHECK: - Type: I32
# CHECK: Count: 1
# CHECK: Body: 108180808000210020000F0B

View File

@ -7,12 +7,14 @@ Sections:
FunctionTypes: [ 0, 0 ]
- Type: GLOBAL
Globals:
- Type: I32
- Index: 0
Type: I32
Mutable: false
InitExpr:
Opcode: I64_CONST
Value: 32
- Type: I32
- Index: 1
Type: I32
Mutable: false
InitExpr:
Opcode: I64_CONST

View File

@ -5,7 +5,8 @@ FileHeader:
Sections:
- Type: GLOBAL
Globals:
- Type: I32
- Index: 0
Type: I32
Mutable: false
InitExpr:
Opcode: I64_CONST
@ -17,7 +18,8 @@ Sections:
# CHECK: Sections:
# CHECK: - Type: GLOBAL
# CHECK: Globals:
# CHECK: - Type: I32
# CHECK: - Index: 0
# CHECK: Type: I32
# CHECK: Mutable: false
# CHECK: InitExpr:
# CHECK: Opcode: I64_CONST

View File

@ -5,7 +5,8 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- I32
- Type: IMPORT

View File

@ -5,7 +5,8 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- I32
- Type: IMPORT

View File

@ -5,7 +5,8 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- I32
- Type: IMPORT

View File

@ -6,7 +6,8 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- F32
- F32

View File

@ -5,11 +5,13 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- F32
- F32
- ReturnType: I64
- Index: 1
ReturnType: I64
ParamTypes:
- F64
- F64

View File

@ -5,13 +5,15 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- Type: FUNCTION
FunctionTypes: [ 0, 0 ]
- Type: GLOBAL
Globals:
- Type: I32
- Index: 0
Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST

View File

@ -9,28 +9,10 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- I32
- Type: FUNCTION
FunctionTypes: [ 0, 0, 0, 0, 0 ]
- Type: GLOBAL
Globals:
- Type: I32
Mutable: false
InitExpr:
Opcode: I64_CONST
Value: 32
- Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST
Value: 64
- Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST
Value: 1024
- Type: IMPORT
Imports:
- Module: env
@ -42,6 +24,28 @@ Sections:
Kind: GLOBAL
GlobalType: I32
GlobalMutable: false
- Type: FUNCTION
FunctionTypes: [ 0, 0, 0, 0, 0 ]
- Type: GLOBAL
Globals:
- Index: 1
Type: I32
Mutable: false
InitExpr:
Opcode: I64_CONST
Value: 32
- Index: 2
Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST
Value: 64
- Index: 3
Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST
Value: 1024
- Type: EXPORT
Exports:
- Name: foo

View File

@ -6,7 +6,8 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- I32
- Type: IMPORT

View File

@ -9,11 +9,10 @@ FileHeader:
Sections:
- Type: TYPE
Signatures:
- ReturnType: I32
- Index: 0
ReturnType: I32
ParamTypes:
- I32
- Type: FUNCTION
FunctionTypes: [ 0, 0, 0, 0 ]
- Type: IMPORT
Imports:
- Module: env
@ -25,19 +24,24 @@ Sections:
Kind: GLOBAL
GlobalType: I32
GlobalMutable: false
- Type: FUNCTION
FunctionTypes: [ 0, 0, 0, 0 ]
- Type: GLOBAL
Globals:
- Type: I32
- Index: 1
Type: I32
Mutable: false
InitExpr:
Opcode: I64_CONST
Value: 32
- Type: I32
- Index: 2
Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST
Value: 64
- Type: I32
- Index: 3
Type: I32
Mutable: false
InitExpr:
Opcode: I32_CONST

View File

@ -186,6 +186,7 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
auto GlobalSec = make_unique<WasmYAML::GlobalSection>();
for (auto &Global : Obj.globals()) {
WasmYAML::Global G;
G.Index = Global.Index;
G.Type = Global.Type;
G.Mutable = Global.Mutable;
G.InitExpr = Global.InitExpr;
@ -230,6 +231,7 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
auto CodeSec = make_unique<WasmYAML::CodeSection>();
for (auto &Func : Obj.functions()) {
WasmYAML::Function Function;
Function.Index = Func.Index;
for (auto &Local : Func.Locals) {
WasmYAML::LocalDecl LocalDecl;
LocalDecl.Type = Local.Type;

View File

@ -45,6 +45,8 @@ private:
int writeSectionContent(raw_ostream &OS, WasmYAML::NameSection &Section);
int writeSectionContent(raw_ostream &OS, WasmYAML::LinkingSection &Section);
WasmYAML::Object &Obj;
uint32_t NumImportedFunctions = 0;
uint32_t NumImportedGlobals = 0;
};
static int writeUint64(raw_ostream &OS, uint64_t Value) {
@ -101,7 +103,7 @@ static int writeInitExpr(const wasm::WasmInitExpr &InitExpr, raw_ostream &OS) {
encodeULEB128(InitExpr.Value.Global, OS);
break;
default:
errs() << "Unknown opcode in init_expr: " << InitExpr.Opcode;
errs() << "Unknown opcode in init_expr: " << InitExpr.Opcode << "\n";
return 1;
}
writeUint8(OS, wasm::WASM_OPCODE_END);
@ -211,7 +213,13 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::TypeSection &Section) {
encodeULEB128(Section.Signatures.size(), OS);
uint32_t ExpectedIndex = 0;
for (const WasmYAML::Signature &Sig : Section.Signatures) {
if (Sig.Index != ExpectedIndex) {
errs() << "Unexpected type index: " << Sig.Index << "\n";
return 1;
}
++ExpectedIndex;
encodeSLEB128(Sig.Form, OS);
encodeULEB128(Sig.ParamTypes.size(), OS);
for (auto ParamType : Sig.ParamTypes)
@ -236,10 +244,12 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
switch (Import.Kind) {
case wasm::WASM_EXTERNAL_FUNCTION:
encodeULEB128(Import.SigIndex, OS);
NumImportedFunctions++;
break;
case wasm::WASM_EXTERNAL_GLOBAL:
encodeSLEB128(Import.GlobalImport.Type, OS);
writeUint8(OS, Import.GlobalImport.Mutable);
NumImportedGlobals++;
break;
case wasm::WASM_EXTERNAL_MEMORY:
writeLimits(Import.Memory, OS);
@ -249,7 +259,7 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
writeLimits(Import.TableImport.TableLimits, OS);
break;
default:
errs() << "Unknown import type: " << Import.Kind;
errs() << "Unknown import type: " << Import.Kind << "\n";
return 1;
}
}
@ -304,7 +314,13 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::GlobalSection &Section) {
encodeULEB128(Section.Globals.size(), OS);
uint32_t ExpectedIndex = NumImportedGlobals;
for (auto &Global : Section.Globals) {
if (Global.Index != ExpectedIndex) {
errs() << "Unexpected global index: " << Global.Index << "\n";
return 1;
}
++ExpectedIndex;
encodeSLEB128(Global.Type, OS);
writeUint8(OS, Global.Mutable);
writeInitExpr(Global.InitExpr, OS);
@ -330,9 +346,15 @@ int WasmWriter::writeSectionContent(raw_ostream &OS,
int WasmWriter::writeSectionContent(raw_ostream &OS,
WasmYAML::CodeSection &Section) {
encodeULEB128(Section.Functions.size(), OS);
uint32_t ExpectedIndex = NumImportedFunctions;
for (auto &Func : Section.Functions) {
std::string OutString;
raw_string_ostream StringStream(OutString);
if (Func.Index != ExpectedIndex) {
errs() << "Unexpected function index: " << Func.Index << "\n";
return 1;
}
++ExpectedIndex;
encodeULEB128(Func.Locals.size(), StringStream);
for (auto &LocalDecl : Func.Locals) {
@ -402,9 +424,18 @@ int WasmWriter::writeWasm(raw_ostream &OS) {
writeUint32(OS, Obj.Header.Version);
// Write each section
uint32_t LastType = 0;
for (const std::unique_ptr<WasmYAML::Section> &Sec : Obj.Sections) {
encodeULEB128(Sec->Type, OS);
uint32_t Type = Sec->Type;
if (Type != wasm::WASM_SEC_CUSTOM) {
if (Type < LastType) {
errs() << "Out of order section type: " << Type << "\n";
return 1;
}
LastType = Type;
}
encodeULEB128(Sec->Type, OS);
std::string OutString;
raw_string_ostream StringStream(OutString);
if (auto S = dyn_cast<WasmYAML::CustomSection>(Sec.get())) {