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,11 @@ StackPointer->Live = true; static WasmSignature NullSignature = {{}, WASM_TYPE_NORESULT}; + // Add synthetic symbols before any others WasmSym::CallCtors = Symtab->addSyntheticFunction( - "__wasm_call_ctors", &NullSignature, WASM_SYMBOL_VISIBILITY_HIDDEN); + "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN, + make(NullSignature, "__wasm_call_ctors")); 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 @@ -44,7 +44,7 @@ class InputChunk { public: - enum Kind { DataSegment, Function }; + enum Kind { DataSegment, Function, SyntheticFunction }; Kind kind() const { return SectionKind; } @@ -120,7 +120,8 @@ : InputChunk(F, InputChunk::Function), Signature(S), Function(Func) {} static bool classof(const InputChunk *C) { - return C->kind() == InputChunk::Function; + return C->kind() == InputChunk::Function || + C->kind() == InputChunk::SyntheticFunction; } StringRef getName() const override { return Function->Name; } @@ -150,13 +151,20 @@ class SyntheticFunction : public InputFunction { public: - SyntheticFunction(const WasmSignature &S, ArrayRef Body, - StringRef Name) - : InputFunction(S, nullptr, nullptr), Name(Name), Body(Body) {} + SyntheticFunction(const WasmSignature &S, StringRef Name) + : InputFunction(S, nullptr, nullptr), Name(Name) { + SectionKind = InputChunk::SyntheticFunction; + } + + static bool classof(const InputChunk *C) { + return C->kind() == InputChunk::SyntheticFunction; + } 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 @@ -41,6 +41,8 @@ void addFile(InputFile *File); std::vector ObjectFiles; + std::vector SyntheticFunctions; + std::vector SyntheticGlobals; void reportRemainingUndefines(); @@ -68,9 +70,8 @@ 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); 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->SyntheticFunctions) + 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->SyntheticGlobals) + 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)); + cast(WasmSym::CallCtors->Function)->setBody(Body); } // Populate InitFunctions vector with init functions from all input objects.