Index: wasm/InputChunks.h =================================================================== --- wasm/InputChunks.h +++ wasm/InputChunks.h @@ -34,6 +34,10 @@ class InputChunk { public: + enum Kind { DataSegment, Function }; + + Kind kind() const { return SectionKind; }; + uint32_t getSize() const { return data().size(); } void copyRelocations(const WasmSection &Section); @@ -54,7 +58,7 @@ std::vector OutRelocations; protected: - InputChunk(const ObjFile *F) : File(F) {} + InputChunk(const ObjFile *F, Kind K) : File(F), SectionKind(K) {} virtual ~InputChunk() = default; void calcRelocations(); virtual ArrayRef data() const = 0; @@ -63,6 +67,7 @@ std::vector Relocations; int32_t OutputOffset = 0; const ObjFile *File; + Kind SectionKind; }; // Represents a WebAssembly data segment which can be included as part of @@ -76,7 +81,9 @@ class InputSegment : public InputChunk { public: InputSegment(const WasmSegment &Seg, const ObjFile *F) - : InputChunk(F), Segment(Seg) {} + : InputChunk(F, InputChunk::DataSegment), Segment(Seg) {} + + static bool classof(const InputChunk *C) { return C->kind() == DataSegment; } // Translate an offset in the input segment to an offset in the output // segment. @@ -113,7 +120,9 @@ public: InputFunction(const WasmSignature &S, const WasmFunction *Func, const ObjFile *F) - : InputChunk(F), Signature(S), Function(Func) {} + : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {} + + static bool classof(const InputChunk *C) { return C->kind() == InputChunk::Function; } virtual StringRef getName() const { return Function->Name; } StringRef getComdat() const override { return Function->Comdat; } Index: wasm/InputFiles.h =================================================================== --- wasm/InputFiles.h +++ wasm/InputFiles.h @@ -117,8 +117,7 @@ uint32_t relocateTableIndex(uint32_t Original) const; Symbol *createDefined(const WasmSymbol &Sym, Symbol::Kind Kind, - const InputSegment *Segment = nullptr, - InputFunction *Function = nullptr, + InputChunk *Chunk = nullptr, uint32_t Address = UINT32_MAX); Symbol *createUndefined(const WasmSymbol &Sym, Symbol::Kind Kind, const WasmSignature *Signature = nullptr); Index: wasm/InputFiles.cpp =================================================================== --- wasm/InputFiles.cpp +++ wasm/InputFiles.cpp @@ -245,8 +245,7 @@ case WasmSymbol::SymbolType::FUNCTION_EXPORT: { InputFunction *Function = getFunction(WasmSym); if (!isExcludedByComdat(Function)) { - S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, nullptr, - Function); + S = createDefined(WasmSym, Symbol::Kind::DefinedFunctionKind, Function); break; } else { Function->Discarded = true; @@ -261,7 +260,7 @@ InputSegment *Segment = getSegment(WasmSym); if (!isExcludedByComdat(Segment)) { S = createDefined(WasmSym, Symbol::Kind::DefinedGlobalKind, - Segment, nullptr, getGlobalValue(WasmSym)); + Segment, getGlobalValue(WasmSym)); break; } else { Segment->Discarded = true; @@ -300,15 +299,14 @@ } Symbol *ObjFile::createDefined(const WasmSymbol &Sym, Symbol::Kind Kind, - const InputSegment *Segment, - InputFunction *Function, uint32_t Address) { + InputChunk *Chunk, uint32_t Address) { Symbol *S; if (Sym.isLocal()) { S = make(Sym.Name, true); - S->update(Kind, this, Sym.Flags, Segment, Function, Address); + S->update(Kind, this, Sym.Flags, Chunk, Address); return S; } - return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Segment, Function, + return Symtab->addDefined(Sym.Name, Kind, Sym.Flags, this, Chunk, Address); } Index: wasm/SymbolTable.h =================================================================== --- wasm/SymbolTable.h +++ wasm/SymbolTable.h @@ -50,8 +50,8 @@ ObjFile *findComdat(StringRef Name) const; Symbol *addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, - InputFile *F, const InputSegment *Segment = nullptr, - InputFunction *Function = nullptr, uint32_t Address = 0); + InputFile *F, + InputChunk *Chunk = nullptr, uint32_t Address = 0); Symbol *addUndefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, InputFile *F, const WasmSignature *Signature = nullptr); Symbol *addUndefinedFunction(StringRef Name, const WasmSignature *Type); Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -119,6 +119,14 @@ " in " + F.getName()); } +static void checkSymbolTypes(const Symbol &Existing, const InputFile &F, + Symbol::Kind Kind, const InputChunk *Chunk) { + const WasmSignature* Sig = nullptr; + if (auto* F = dyn_cast_or_null(Chunk)) + Sig = &F->Signature; + return checkSymbolTypes(Existing, F, Kind, Sig); +} + Symbol *SymbolTable::addDefinedFunction(StringRef Name, const WasmSignature *Type, uint32_t Flags) { @@ -156,26 +164,25 @@ Symbol *SymbolTable::addDefined(StringRef Name, Symbol::Kind Kind, uint32_t Flags, InputFile *F, - const InputSegment *Segment, - InputFunction *Function, uint32_t Address) { + InputChunk *Chunk, uint32_t Address) { DEBUG(dbgs() << "addDefined: " << Name << " addr:" << Address << "\n"); Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); if (WasInserted) { - S->update(Kind, F, Flags, Segment, Function, Address); + S->update(Kind, F, Flags, Chunk, Address); } else if (S->isLazy()) { // The existing symbol is lazy. Replace it without checking types since // lazy symbols don't have any type information. DEBUG(dbgs() << "replacing existing lazy symbol: " << Name << "\n"); - S->update(Kind, F, Flags, Segment, Function, Address); + S->update(Kind, F, Flags, Chunk, Address); } else if (!S->isDefined()) { // The existing symbol table entry is undefined. The new symbol replaces // it, after checking the type matches DEBUG(dbgs() << "resolving existing undefined symbol: " << Name << "\n"); - checkSymbolTypes(*S, *F, Kind, Function ? &Function->Signature : nullptr); - S->update(Kind, F, Flags, Segment, Function, Address); + checkSymbolTypes(*S, *F, Kind, Chunk); + S->update(Kind, F, Flags, Chunk, Address); } else if ((Flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) { // the new symbol is weak we can ignore it DEBUG(dbgs() << "existing symbol takes precedence\n"); @@ -183,8 +190,8 @@ // the new symbol is not weak and the existing symbol is, so we replace // it DEBUG(dbgs() << "replacing existing weak symbol\n"); - checkSymbolTypes(*S, *F, Kind, Function ? &Function->Signature : nullptr); - S->update(Kind, F, Flags, Segment, Function, Address); + checkSymbolTypes(*S, *F, Kind, Chunk); + S->update(Kind, F, Flags, Chunk, Address); } else { // neither symbol is week. They conflict. reportDuplicate(S, F); Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -21,8 +21,7 @@ namespace wasm { class InputFile; -class InputSegment; -class InputFunction; +class InputChunk; class Symbol { public: @@ -62,6 +61,7 @@ // Returns the file from which this symbol was created. InputFile *getFile() const { return File; } + InputChunk *getChunk() const { return Chunk; } bool hasFunctionType() const { return FunctionType != nullptr; } const WasmSignature &getFunctionType() const; @@ -92,12 +92,11 @@ void setVirtualAddress(uint32_t VA); void update(Kind K, InputFile *F = nullptr, uint32_t Flags = 0, - const InputSegment *Segment = nullptr, - InputFunction *Function = nullptr, uint32_t Address = UINT32_MAX); + InputChunk *chunk = nullptr, + uint32_t Address = UINT32_MAX); void setArchiveSymbol(const Archive::Symbol &Sym) { ArchiveSymbol = Sym; } const Archive::Symbol &getArchiveSymbol() { return ArchiveSymbol; } - InputFunction *getFunction() { return Function; } protected: uint32_t Flags; @@ -107,8 +106,7 @@ Archive::Symbol ArchiveSymbol = {nullptr, 0, 0}; Kind SymbolKind = InvalidKind; InputFile *File = nullptr; - const InputSegment *Segment = nullptr; - InputFunction *Function = nullptr; + InputChunk *Chunk = nullptr; llvm::Optional OutputIndex; llvm::Optional TableIndex; const WasmSignature *FunctionType = nullptr; Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -23,8 +23,8 @@ using namespace lld::wasm; const WasmSignature &Symbol::getFunctionType() const { - if (Function != nullptr) - return Function->Signature; + if (Chunk != nullptr) + return dyn_cast(Chunk)->Signature; assert(FunctionType != nullptr); return *FunctionType; @@ -32,25 +32,25 @@ void Symbol::setFunctionType(const WasmSignature *Type) { assert(FunctionType == nullptr); - assert(Function == nullptr); + assert(!Chunk); FunctionType = Type; } uint32_t Symbol::getVirtualAddress() const { assert(isGlobal()); DEBUG(dbgs() << "getVirtualAddress: " << getName() << "\n"); - return Segment ? Segment->translateVA(VirtualAddress) : VirtualAddress; + return Chunk ? dyn_cast(Chunk)->translateVA(VirtualAddress) : VirtualAddress; } bool Symbol::hasOutputIndex() const { - if (Function) - return Function->hasOutputIndex(); + if (auto* F = dyn_cast_or_null(Chunk)) + return F->hasOutputIndex(); return OutputIndex.hasValue(); } uint32_t Symbol::getOutputIndex() const { - if (Function) - return Function->getOutputIndex(); + if (auto* F = dyn_cast_or_null(Chunk)) + return F->getOutputIndex(); return OutputIndex.getValue(); } @@ -62,20 +62,20 @@ void Symbol::setOutputIndex(uint32_t Index) { DEBUG(dbgs() << "setOutputIndex " << Name << " -> " << Index << "\n"); - assert(!Function); + assert(!dyn_cast_or_null(Chunk)); assert(!OutputIndex.hasValue()); OutputIndex = Index; } uint32_t Symbol::getTableIndex() const { - if (Function) - return Function->getTableIndex(); + if (auto* F = dyn_cast_or_null(Chunk)) + return F->getTableIndex(); return TableIndex.getValue(); } bool Symbol::hasTableIndex() const { - if (Function) - return Function->hasTableIndex(); + if (auto* F = dyn_cast_or_null(Chunk)) + return F->hasTableIndex(); return TableIndex.hasValue(); } @@ -83,8 +83,8 @@ // For imports, we set the table index here on the Symbol; for defined // functions we set the index on the InputFunction so that we don't export // the same thing twice (keeps the table size down). - if (Function) { - Function->setTableIndex(Index); + if (auto* F = dyn_cast_or_null(Chunk)) { + F->setTableIndex(Index); return; } DEBUG(dbgs() << "setTableIndex " << Name << " -> " << Index << "\n"); @@ -93,13 +93,12 @@ } void Symbol::update(Kind K, InputFile *F, uint32_t Flags_, - const InputSegment *Seg, InputFunction *Func, + InputChunk *Chunk_, uint32_t Address) { SymbolKind = K; File = F; Flags = Flags_; - Segment = Seg; - Function = Func; + Chunk = Chunk_; if (Address != UINT32_MAX) setVirtualAddress(Address); } Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -648,7 +648,7 @@ continue; if (Sym->isGlobal()) continue; - if (Sym->getFunction()->Discarded) + if (Sym->getChunk()->Discarded) continue; if ((Sym->isHidden() || Sym->isLocal()) && !ExportHidden)