[PATCH] D43264: [WebAssembly] Add explicit symbol table

Rui Ueyama via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 13 17:22:57 PST 2018


ruiu added inline comments.


================
Comment at: wasm/InputChunks.h:183
+// form the final GLOBALS section.
+class InputGlobal : public InputChunk {
+public:
----------------
Chunk is a concept to represent some contiguous bytes in an input file or a synthesized one. Essentially, a chunk is a section or something similar.

It doesn't seems to me that this class falls in that category, though I may be wrong due to lack of knowledge on wasm. Is this an appropriate abstraction?


================
Comment at: wasm/InputFiles.cpp:248
       }
-    }
-    case WasmSymbol::SymbolType::FUNCTION_IMPORT:
-      S = createUndefined(WasmSym, Symbol::Kind::UndefinedFunctionKind,
-                          getFunctionSig(WasmSym));
+      S = createUndefined(WasmSym);
       break;
----------------
I'd just call `Symbols.push_back(createUndefined(WasmSym))` and remove `S`.

Or, I'd move this switch-cases to a new function returning `Symbol *` and call like this:

  Symbols.push_back(createSymbol(WasmSym));


================
Comment at: wasm/InputFiles.h:111
   ArrayRef<Symbol *> getSymbols() const { return Symbols; }
-
-  FunctionSymbol *getFunctionSymbol(uint32_t Index) const {
-    return cast<FunctionSymbol>(FunctionSymbols[Index]);
-  }
-
-  GlobalSymbol *getGlobalSymbol(uint32_t Index) const {
-    return cast<GlobalSymbol>(GlobalSymbols[Index]);
-  }
+  Symbol *getSymbol(uint32_t Symbol) const { return Symbols[Symbol]; }
+  FunctionSymbol *getFunctionSymbol(uint32_t Index) const;
----------------
Symbol -> Index


================
Comment at: wasm/InputFiles.h:132-133
   InputSegment *getSegment(const WasmSymbol &WasmSym) const;
-  const WasmSignature *getFunctionSig(const WasmSymbol &Sym) const;
-  uint32_t getGlobalValue(const WasmSymbol &Sym) const;
+  std::pair<uint32_t, uint32_t>
+  getDataAddressAndSize(const WasmSymbol &WasmSym) const;
   InputFunction *getFunction(const WasmSymbol &Sym) const;
----------------
It seems more straightforward if you define getDataAddress and getDataSize.


================
Comment at: wasm/MarkLive.cpp:73-75
+      if (Reloc.Type == R_WEBASSEMBLY_TYPE_INDEX_LEB)
+        continue;
+      Enqueue(Chunk.File->getSymbol(Reloc.Index));
----------------
Since we skip only one line, I'd flip the condition so that we can wreite

  for (...)
    if (Reloc.Type != ...)
      Enqueue(...);


================
Comment at: wasm/SymbolTable.cpp:134-137
+  error(toString(NewType) + " type mismatch: " + Existing.getName() +
+        "\n>>> defined as " + OldSigStr + " in " +
+        toString(Existing.getFile()) + "\n>>> defined as " + NewSigStr +
+        " in " + F.getName());
----------------
If you wrap this up as a lambda

  auto Error = [&](const Twine &Old, const Twine &New) {
    error(toString(NewType) + " type mismatch: " + Existing.getName() +
          "\n>>> defined as " + Old + " in " +
          toString(Existing.getFile()) + "\n>>> defined as " + New +
          " in " + F.getName());
  };

then you can eliminate OldSigStr and NewSigStr variables from this function.


================
Comment at: wasm/Symbols.cpp:140
+  const InputSegment *Segment = dyn_cast<InputSegment>(Chunk);
+  return Segment->OutputSegmentOffset + (VirtualAddress - Segment->startVA());
+}
----------------
Extraneous ()


================
Comment at: wasm/Symbols.cpp:201
+  llvm_unreachable("Invalid symbol type");
+  return "";
+}
----------------
I believe llvm_unreachable is defined as _Noreturn, so you don't need this `return ""` after llvm_noreturn.


================
Comment at: wasm/Symbols.cpp:217
+    llvm_unreachable("kind with no type");
+    return static_cast<WasmSymbolType>(-1);
+  }
----------------
Ditto


================
Comment at: wasm/Symbols.h:152-154
+  void setChunk(InputChunk* C) {
+    Chunk = C;
+  }
----------------
A function is created for a chunk, so it is a bit odd that there's a situation that you have to change a chunk for an existing function symbol. What is this for?


================
Comment at: wasm/Symbols.h:238-244
+  DefinedGlobal(StringRef Name, uint32_t Flags, InputFile *File, InputChunk *C)
+      : GlobalSymbol(Name, DefinedGlobalKind, Flags, File, C) {}
+
+  DefinedGlobal(StringRef Name, uint32_t Flags, const WasmGlobalType *Type)
+      : GlobalSymbol(Name, DefinedGlobalKind, Flags, nullptr, nullptr) {
+    setGlobalType(Type);
+  }
----------------
Why does this have two constructors?


================
Comment at: wasm/Writer.cpp:194-198
+    } else if (auto *GlobalSym = dyn_cast<GlobalSymbol>(Sym)) {
+      Import.Kind = WASM_EXTERNAL_GLOBAL;
+      Import.Global = GlobalSym->getGlobalType();
+    } else {
+      llvm_unreachable("invalid import type");
----------------
This is where you want to use cast instead of dyn_cast.

  } else {
     auto *GlobalSym = cast<GlobalSymbol>(Sym);
     ....
  }


================
Comment at: wasm/Writer.cpp:412-416
+      uint32_t Kind = Sym->isFunction()
+                          ? llvm::wasm::WASM_SYMBOL_TYPE_FUNCTION
+                          : Sym->isGlobal()
+                                ? llvm::wasm::WASM_SYMBOL_TYPE_GLOBAL
+                                : llvm::wasm::WASM_SYMBOL_TYPE_DATA;
----------------
This nested ?: operators look a bit fancy to me. I'd perhaps make this a tiny helper function that takes a Sym and returns a Kind.


================
Comment at: wasm/WriterUtils.cpp:221-225
+  SmallString<128> S;
+  if (Sig.Mutable)
+    S += "mutable ";
+  S += toString(static_cast<ValType>(Sig.Type));
+  return S.str();
----------------
This is perhaps a personal taste, but isn't this better?

  std::string S = toString(static_cast<ValType>(Sig.Type));
  if (Sig.Mutable)
    return "mutable " + S;
  return S;


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D43264





More information about the llvm-commits mailing list