Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -9,6 +9,7 @@ #include "lld/Common/Driver.h" #include "Config.h" +#include "InputChunks.h" #include "InputGlobal.h" #include "MarkLive.h" #include "SymbolTable.h" @@ -295,9 +296,13 @@ StackPointer->Live = true; static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT}; + InputFunction *CallCtors = + make(NullSignature, ArrayRef(), + "__wasm_call_ctors"); + // Add synthetic symbols before any others WasmSym::CallCtors = Symtab->addSyntheticFunction( - "__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN); + CallCtors->getName(), WASM_SYMBOL_VISIBILITY_HIDDEN, CallCtors); WasmSym::StackPointer = Symtab->addSyntheticGlobal( "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer); WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0); Index: wasm/InputChunks.h =================================================================== --- wasm/InputChunks.h +++ wasm/InputChunks.h @@ -157,6 +157,8 @@ StringRef getName() const override { return Name; } StringRef getComdat() const override { return StringRef(); } + void setBody(ArrayRef Body_) { Body = Body_; } + protected: ArrayRef data() const override { return Body; } Index: wasm/SymbolTable.h =================================================================== --- wasm/SymbolTable.h +++ wasm/SymbolTable.h @@ -47,6 +47,13 @@ ArrayRef getSymbols() const { return SymVector; } Symbol *find(StringRef Name); + ArrayRef getSyntheticFunctions() const { + return SyntheticFunctions; + } + ArrayRef getSyntheticGlobals() const { + return SyntheticGlobals; + } + Symbol *addDefinedFunction(StringRef Name, uint32_t Flags, InputFile *File, InputFunction *Function); Symbol *addDefinedData(StringRef Name, uint32_t Flags, InputFile *File, @@ -68,15 +75,16 @@ DefinedData *addSyntheticDataSymbol(StringRef Name, uint32_t Flags); DefinedGlobal *addSyntheticGlobal(StringRef Name, uint32_t Flags, InputGlobal *Global); - DefinedFunction *addSyntheticFunction(StringRef Name, - const WasmSignature *Type, - uint32_t Flags); + DefinedFunction *addSyntheticFunction(StringRef Name, uint32_t Flags, + InputFunction *Function); private: std::pair insert(StringRef Name); llvm::DenseMap SymMap; std::vector SymVector; + std::vector SyntheticFunctions; + std::vector SyntheticGlobals; llvm::DenseMap Comdats; }; Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -119,11 +119,13 @@ } DefinedFunction *SymbolTable::addSyntheticFunction(StringRef Name, - const WasmSignature *Type, - uint32_t Flags) { + uint32_t Flags, + InputFunction *Function) { DEBUG(dbgs() << "addSyntheticFunction: " << Name << "\n"); assert(!find(Name)); - return replaceSymbol(insert(Name).first, Name, Flags, Type); + SyntheticFunctions.emplace_back(Function); + return replaceSymbol(insert(Name).first, Name, Flags, + nullptr, Function); } DefinedData *SymbolTable::addSyntheticDataSymbol(StringRef Name, @@ -137,6 +139,7 @@ InputGlobal *Global) { DEBUG(dbgs() << "addSyntheticGlobal: " << Name << " -> " << Global << "\n"); assert(!find(Name)); + SyntheticGlobals.emplace_back(Global); return replaceSymbol(insert(Name).first, Name, Flags, nullptr, Global); } Index: wasm/Symbols.h =================================================================== --- wasm/Symbols.h +++ wasm/Symbols.h @@ -134,14 +134,9 @@ class DefinedFunction : public FunctionSymbol { public: - // Primary constructor for file-defined functions. DefinedFunction(StringRef Name, uint32_t Flags, InputFile *F, InputFunction *Function); - // Second constructor used when creating synthetic functions. - DefinedFunction(StringRef Name, uint32_t Flags, const WasmSignature *Type) - : FunctionSymbol(Name, DefinedFunctionKind, Flags, nullptr, Type) {} - static bool classof(const Symbol *S) { return S->kind() == DefinedFunctionKind; } Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -750,16 +750,24 @@ void Writer::assignIndexes() { uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size(); + auto AddDefinedFunction = [&](InputFunction *Func) { + if (!Func->Live) + return; + InputFunctions.emplace_back(Func); + Func->setOutputIndex(FunctionIndex++); + }; + for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Functions: " << File->getName() << "\n"); - for (InputFunction *Func : File->Functions) { - if (!Func->Live) - continue; - InputFunctions.emplace_back(Func); - Func->setOutputIndex(FunctionIndex++); - } + for (InputFunction *Func : File->Functions) + AddDefinedFunction(Func); } + // TODO Move synthetic functions to come before (so __wasm_call_ctors can be + // compiled immediately by the browser). Will reorder tests. + for (InputFunction *Func : Symtab->getSyntheticFunctions()) + AddDefinedFunction(Func); + uint32_t TableIndex = kInitialTableOffset; auto HandleRelocs = [&](InputChunk *Chunk) { if (!Chunk->Live) @@ -806,8 +814,8 @@ } }; - if (WasmSym::StackPointer) - AddDefinedGlobal(WasmSym::StackPointer->Global); + for (InputGlobal *Global : Symtab->getSyntheticGlobals()) + AddDefinedGlobal(Global); for (ObjFile *File : Symtab->ObjectFiles) { DEBUG(dbgs() << "Globals: " << File->getName() << "\n"); @@ -852,8 +860,6 @@ // Create synthetic "__wasm_call_ctors" function based on ctor functions // in input object. void Writer::createCtorFunction() { - uint32_t FunctionIndex = NumImportedFunctions + InputFunctions.size(); - // First write the body's contents to a string. std::string BodyContent; { @@ -874,15 +880,8 @@ OS << BodyContent; } - const WasmSignature *Sig = WasmSym::CallCtors->getFunctionType(); - SyntheticFunction *F = - make(*Sig, toArrayRef(Saver.save(FunctionBody)), - WasmSym::CallCtors->getName()); - - F->setOutputIndex(FunctionIndex); - F->Live = true; - WasmSym::CallCtors->Function = F; - InputFunctions.emplace_back(F); + ArrayRef Body = toArrayRef(Saver.save(FunctionBody)); + static_cast(WasmSym::CallCtors->Function)->setBody(Body); } // Populate InitFunctions vector with init functions from all input objects.