diff options
author | Andy Wingo <wingo@igalia.com> | 2021-03-04 10:30:00 +0100 |
---|---|---|
committer | Andy Wingo <wingo@igalia.com> | 2021-03-05 11:45:15 +0100 |
commit | a5a3659de788fe4972ac5e91a455add85d037a33 (patch) | |
tree | 49eab075a5ca0ac128e5c59535b7053c5fbf957e /llvm/lib/Object/WasmObjectFile.cpp | |
parent | 4295ae96cdf275cdda8bded9271960a4cac11fb2 (diff) | |
download | llvm-a5a3659de788fe4972ac5e91a455add85d037a33.zip llvm-a5a3659de788fe4972ac5e91a455add85d037a33.tar.gz llvm-a5a3659de788fe4972ac5e91a455add85d037a33.tar.bz2 |
[WebAssembly][yaml2obj][obj2yaml] Elem sections for nonzero tables
With reference types, tables can have non-zero table numbers. This
commit adds support for element sections against these tables.
Differential Revision: https://reviews.llvm.org/D97923
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 65 |
1 files changed, 53 insertions, 12 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 40f4688..7fbb186 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -598,8 +598,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { case wasm::WASM_SYMBOL_TYPE_TABLE: Info.ElementIndex = readVaruint32(Ctx); - if (!isValidTableIndex(Info.ElementIndex) || - IsDefined != isDefinedTableIndex(Info.ElementIndex)) + if (!isValidTableNumber(Info.ElementIndex) || + IsDefined != isDefinedTableNumber(Info.ElementIndex)) return make_error<GenericBinaryError>("invalid table symbol index", object_error::parse_failed); if (!IsDefined && (Info.Flags & wasm::WASM_SYMBOL_BINDING_MASK) == @@ -608,8 +608,8 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { object_error::parse_failed); if (IsDefined) { Info.Name = readString(Ctx); - unsigned TableIndex = Info.ElementIndex - NumImportedTables; - wasm::WasmTable &Table = Tables[TableIndex]; + unsigned TableNumber = Info.ElementIndex - NumImportedTables; + wasm::WasmTable &Table = Tables[TableNumber]; TableType = &Table.Type; if (Table.SymbolName.empty()) Table.SymbolName = Info.Name; @@ -1220,7 +1220,7 @@ bool WasmObjectFile::isValidGlobalIndex(uint32_t Index) const { return Index < NumImportedGlobals + Globals.size(); } -bool WasmObjectFile::isValidTableIndex(uint32_t Index) const { +bool WasmObjectFile::isValidTableNumber(uint32_t Index) const { return Index < NumImportedTables + Tables.size(); } @@ -1228,8 +1228,8 @@ bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const { return Index >= NumImportedGlobals && isValidGlobalIndex(Index); } -bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const { - return Index >= NumImportedTables && isValidTableIndex(Index); +bool WasmObjectFile::isDefinedTableNumber(uint32_t Index) const { + return Index >= NumImportedTables && isValidTableNumber(Index); } bool WasmObjectFile::isValidEventIndex(uint32_t Index) const { @@ -1340,13 +1340,54 @@ Error WasmObjectFile::parseElemSection(ReadContext &Ctx) { ElemSegments.reserve(Count); while (Count--) { wasm::WasmElemSegment Segment; - Segment.TableIndex = readVaruint32(Ctx); - if (Segment.TableIndex != 0) { - return make_error<GenericBinaryError>("invalid TableIndex", + Segment.Flags = readVaruint32(Ctx); + + uint32_t SupportedFlags = wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER | + wasm::WASM_ELEM_SEGMENT_IS_PASSIVE | + wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS; + if (Segment.Flags & ~SupportedFlags) + return make_error<GenericBinaryError>( + "Unsupported flags for element segment", object_error::parse_failed); + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_TABLE_NUMBER) + Segment.TableNumber = readVaruint32(Ctx); + else + Segment.TableNumber = 0; + if (!isValidTableNumber(Segment.TableNumber)) + return make_error<GenericBinaryError>("invalid TableNumber", object_error::parse_failed); + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_IS_PASSIVE) { + Segment.Offset.Opcode = wasm::WASM_OPCODE_I32_CONST; + Segment.Offset.Value.Int32 = 0; + } else { + if (Error Err = readInitExpr(Segment.Offset, Ctx)) + return Err; } - if (Error Err = readInitExpr(Segment.Offset, Ctx)) - return Err; + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_MASK_HAS_ELEM_KIND) { + Segment.ElemKind = readUint8(Ctx); + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS) { + if (Segment.ElemKind != uint8_t(wasm::ValType::FUNCREF) && + Segment.ElemKind != uint8_t(wasm::ValType::EXTERNREF)) { + return make_error<GenericBinaryError>("invalid reference type", + object_error::parse_failed); + } + } else { + if (Segment.ElemKind != 0) + return make_error<GenericBinaryError>("invalid elemtype", + object_error::parse_failed); + Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF); + } + } else { + Segment.ElemKind = uint8_t(wasm::ValType::FUNCREF); + } + + if (Segment.Flags & wasm::WASM_ELEM_SEGMENT_HAS_INIT_EXPRS) + return make_error<GenericBinaryError>( + "elem segment init expressions not yet implemented", + object_error::parse_failed); + uint32_t NumElems = readVaruint32(Ctx); while (NumElems--) { Segment.Functions.push_back(readVaruint32(Ctx)); |