[WebAssembly] Factor out WasmTableType in binary format
authorAndy Wingo <wingo@igalia.com>
Wed, 25 Nov 2020 15:54:31 +0000 (07:54 -0800)
committerSam Clegg <sbc@chromium.org>
Wed, 25 Nov 2020 16:00:08 +0000 (08:00 -0800)
This commit factors out a WasmTableType definition from WasmTable, as is
the case for WasmGlobal and other data types.  Also add support for
extracting the SymbolName for a table from the linking section's symbol
table.

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

lld/wasm/SyntheticSections.cpp
lld/wasm/WriterUtils.cpp
lld/wasm/WriterUtils.h
llvm/include/llvm/BinaryFormat/Wasm.h
llvm/lib/MC/WasmObjectWriter.cpp
llvm/lib/Object/WasmObjectFile.cpp
llvm/tools/obj2yaml/wasm2yaml.cpp

index 407eb8084d0e54241a08c6554e2571f62860b566..3e0581cbcfc4d9f8c49c45ecbac398c6f00d1623 100644 (file)
@@ -223,7 +223,7 @@ void TableSection::writeBody() {
     limits = {0, tableSize, 0};
   else
     limits = {WASM_LIMITS_FLAG_HAS_MAX, tableSize, tableSize};
-  writeTableType(os, WasmTable{0, WASM_TYPE_FUNCREF, limits});
+  writeTableType(os, WasmTableType{WASM_TYPE_FUNCREF, limits});
 }
 
 void MemorySection::writeBody() {
index cd221855a12bf71b8781452e0dbac8104dc352b6..81fcee4e68fed5133fa2d01ed4c0e6744d2ef8ba 100644 (file)
@@ -195,7 +195,7 @@ void writeEvent(raw_ostream &os, const WasmEvent &event) {
   writeEventType(os, event.Type);
 }
 
-void writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type) {
+void writeTableType(raw_ostream &os, const WasmTableType &type) {
   writeU8(os, WASM_TYPE_FUNCREF, "table type");
   writeLimits(os, type.Limits);
 }
index 86df768af5c60f77cfb213f7e67985e2eb13ae0b..98f5ab1fbf3b14e132373c6d97fde883e15edeaa 100644 (file)
@@ -54,7 +54,7 @@ void writeEventType(raw_ostream &os, const llvm::wasm::WasmEventType &type);
 
 void writeEvent(raw_ostream &os, const llvm::wasm::WasmEvent &event);
 
-void writeTableType(raw_ostream &os, const llvm::wasm::WasmTable &type);
+void writeTableType(raw_ostream &os, const llvm::wasm::WasmTableType &type);
 
 void writeImport(raw_ostream &os, const llvm::wasm::WasmImport &import);
 
index f1441c7e0794706364785cc3a7970b42c6fb8cdb..adcd9d3644316215716137f8137b5b3b64314cb3 100644 (file)
@@ -67,12 +67,17 @@ struct WasmLimits {
   uint64_t Maximum;
 };
 
-struct WasmTable {
-  uint32_t Index;
+struct WasmTableType {
   uint8_t ElemType;
   WasmLimits Limits;
 };
 
+struct WasmTable {
+  uint32_t Index;
+  WasmTableType Type;
+  StringRef SymbolName; // from the "linking" section
+};
+
 struct WasmInitExpr {
   uint8_t Opcode;
   union {
@@ -115,7 +120,7 @@ struct WasmImport {
   union {
     uint32_t SigIndex;
     WasmGlobalType Global;
-    WasmTable Table;
+    WasmTableType Table;
     WasmLimits Memory;
     WasmEventType Event;
   };
index 0cf6e310ae3224acd948781bfcd2d90de8b6f6d1..029b776fd7744f73dc73cc769f391a70318fc1da 100644 (file)
@@ -848,11 +848,11 @@ void WasmObjectWriter::writeTableSection(ArrayRef<wasm::WasmTable> Tables) {
 
   encodeULEB128(Tables.size(), W->OS);
   for (const wasm::WasmTable &Table : Tables) {
-    encodeULEB128(Table.ElemType, W->OS);
-    encodeULEB128(Table.Limits.Flags, W->OS);
-    encodeULEB128(Table.Limits.Initial, W->OS);
-    if (Table.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
-      encodeULEB128(Table.Limits.Maximum, W->OS);
+    encodeULEB128(Table.Type.ElemType, W->OS);
+    encodeULEB128(Table.Type.Limits.Flags, W->OS);
+    encodeULEB128(Table.Type.Limits.Initial, W->OS);
+    if (Table.Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX)
+      encodeULEB128(Table.Type.Limits.Maximum, W->OS);
   }
   endSection(Section);
 }
@@ -1527,10 +1527,10 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
       if (WS.isDefined()) {
         assert(WasmIndices.count(&WS) == 0);
         wasm::WasmTable Table;
-        Table.ElemType = static_cast<uint8_t>(WS.getTableType());
         Table.Index = NumTableImports + Tables.size();
+        Table.Type.ElemType = static_cast<uint8_t>(WS.getTableType());
         // FIXME: Work on custom limits is ongoing
-        Table.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
+        Table.Type.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
 
         WasmIndices[&WS] = Table.Index;
         Tables.push_back(Table);
index 2504fda1a8cb3a71bee714c8dd86816162755ecc..a9a0ad51192fcefff204306351891a47e59dcfa2 100644 (file)
@@ -214,12 +214,11 @@ static wasm::WasmLimits readLimits(WasmObjectFile::ReadContext &Ctx) {
   return Result;
 }
 
-static wasm::WasmTable readTable(WasmObjectFile::ReadContext &Ctx) {
-  wasm::WasmTable Table;
-  Table.ElemType = readUint8(Ctx);
-  Table.Limits = readLimits(Ctx);
-  // The caller needs to set Table.Index field for Table
-  return Table;
+static wasm::WasmTableType readTableType(WasmObjectFile::ReadContext &Ctx) {
+  wasm::WasmTableType TableType;
+  TableType.ElemType = readUint8(Ctx);
+  TableType.Limits = readLimits(Ctx);
+  return TableType;
 }
 
 static Error readSection(WasmSection &Section, WasmObjectFile::ReadContext &Ctx,
@@ -597,7 +596,9 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) {
         Info.Name = readString(Ctx);
         unsigned TableIndex = Info.ElementIndex - NumImportedTables;
         wasm::WasmTable &Table = Tables[TableIndex];
-        TableType = Table.ElemType;
+        TableType = Table.Type.ElemType;
+        if (Table.SymbolName.empty())
+          Table.SymbolName = Info.Name;
       } else {
         return make_error<GenericBinaryError>("undefined table symbol",
                                               object_error::parse_failed);
@@ -1014,8 +1015,7 @@ Error WasmObjectFile::parseImportSection(ReadContext &Ctx) {
         HasMemory64 = true;
       break;
     case wasm::WASM_EXTERNAL_TABLE: {
-      Im.Table = readTable(Ctx);
-      Im.Table.Index = NumImportedTables + Tables.size();
+      Im.Table = readTableType(Ctx);
       NumImportedTables++;
       auto ElemType = Im.Table.ElemType;
       if (ElemType != wasm::WASM_TYPE_FUNCREF &&
@@ -1063,10 +1063,11 @@ Error WasmObjectFile::parseTableSection(ReadContext &Ctx) {
   uint32_t Count = readVaruint32(Ctx);
   Tables.reserve(Count);
   while (Count--) {
-    wasm::WasmTable T = readTable(Ctx);
+    wasm::WasmTable T;
+    T.Type = readTableType(Ctx);
     T.Index = NumImportedTables + Tables.size();
     Tables.push_back(T);
-    auto ElemType = Tables.back().ElemType;
+    auto ElemType = Tables.back().Type.ElemType;
     if (ElemType != wasm::WASM_TYPE_FUNCREF &&
         ElemType != wasm::WASM_TYPE_EXTERNREF) {
       return make_error<GenericBinaryError>("Invalid table element type",
index 9ca351e1ce9fbc1a06c162488940ddfd34dfc547..d47b7bee199b6278ee290d863ad60e9d1a04cb75 100644 (file)
@@ -31,16 +31,6 @@ public:
 
 } // namespace
 
-static WasmYAML::Table makeTable(const wasm::WasmTable &Table) {
-  WasmYAML::Table T;
-  T.ElemType = Table.ElemType;
-  T.TableLimits.Flags = Table.Limits.Flags;
-  T.TableLimits.Initial = Table.Limits.Initial;
-  T.TableLimits.Maximum = Table.Limits.Maximum;
-  T.Index = Table.Index;
-  return T;
-}
-
 static WasmYAML::Limits makeLimits(const wasm::WasmLimits &Limits) {
   WasmYAML::Limits L;
   L.Flags = Limits.Flags;
@@ -49,6 +39,15 @@ static WasmYAML::Limits makeLimits(const wasm::WasmLimits &Limits) {
   return L;
 }
 
+static WasmYAML::Table makeTable(uint32_t Index,
+                                 const wasm::WasmTableType &Type) {
+  WasmYAML::Table T;
+  T.Index = Index;
+  T.ElemType = Type.ElemType;
+  T.TableLimits = makeLimits(Type.Limits);
+  return T;
+}
+
 std::unique_ptr<WasmYAML::CustomSection>
 WasmDumper::dumpCustomSection(const WasmSection &WasmSec) {
   std::unique_ptr<WasmYAML::CustomSection> CustomSec;
@@ -234,7 +233,9 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
           Im.EventImport.SigIndex = Import.Event.SigIndex;
           break;
         case wasm::WASM_EXTERNAL_TABLE:
-          Im.TableImport = makeTable(Import.Table);
+          // FIXME: Currently we always output an index of 0 for any imported
+          // table.
+          Im.TableImport = makeTable(0, Import.Table);
           break;
         case wasm::WASM_EXTERNAL_MEMORY:
           Im.Memory = makeLimits(Import.Memory);
@@ -256,7 +257,7 @@ ErrorOr<WasmYAML::Object *> WasmDumper::dump() {
     case wasm::WASM_SEC_TABLE: {
       auto TableSec = std::make_unique<WasmYAML::TableSection>();
       for (const wasm::WasmTable &Table : Obj.tables()) {
-        TableSec->Tables.push_back(makeTable(Table));
+        TableSec->Tables.push_back(makeTable(Table.Index, Table.Type));
       }
       S = std::move(TableSec);
       break;