2323#include < string>
2424
2525namespace lld {
26+ enum Flavor {
27+ Invalid,
28+ Gnu, // -flavor gnu
29+ MinGW, // -flavor gnu MinGW
30+ WinLink, // -flavor link
31+ Darwin, // -flavor darwin
32+ Wasm, // -flavor wasm
33+ };
34+
35+ using Driver = bool (*)(llvm::ArrayRef<const char *>, llvm::raw_ostream &,
36+ llvm::raw_ostream &, bool , bool );
37+
38+ struct DriverDef {
39+ Flavor f;
40+ Driver d;
41+ };
42+
43+ struct Result {
44+ int retCode;
45+ bool canRunAgain;
46+ };
47+
48+ Result lldMain (llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
49+ llvm::raw_ostream &stderrOS, llvm::ArrayRef<DriverDef> drivers);
50+
2651namespace wasm {
2752bool link (llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
2853 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput);
@@ -51,13 +76,14 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
5176 llvm::TargetMachine *TargetMachine = Target->createTargetMachine (
5277 PTU.TheModule ->getTargetTriple (), " " , " " , TO, llvm::Reloc::Model::PIC_);
5378 PTU.TheModule ->setDataLayout (TargetMachine->createDataLayout ());
54- std::string OutputFileName = PTU.TheModule ->getName ().str () + " .wasm" ;
79+ std::string ObjectFileName = PTU.TheModule ->getName ().str () + " .o" ;
80+ std::string BinaryFileName = PTU.TheModule ->getName ().str () + " .wasm" ;
5581
5682 std::error_code Error;
57- llvm::raw_fd_ostream OutputFile (llvm::StringRef (OutputFileName ), Error);
83+ llvm::raw_fd_ostream ObjectFileOutput (llvm::StringRef (ObjectFileName ), Error);
5884
5985 llvm::legacy::PassManager PM;
60- if (TargetMachine->addPassesToEmitFile (PM, OutputFile , nullptr ,
86+ if (TargetMachine->addPassesToEmitFile (PM, ObjectFileOutput , nullptr ,
6187 llvm::CodeGenFileType::ObjectFile)) {
6288 return llvm::make_error<llvm::StringError>(
6389 " Wasm backend cannot produce object." , llvm::inconvertibleErrorCode ());
@@ -69,27 +95,30 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
6995 llvm::inconvertibleErrorCode ());
7096 }
7197
72- OutputFile .close ();
98+ ObjectFileOutput .close ();
7399
74100 std::vector<const char *> LinkerArgs = {" wasm-ld" ,
75- " -pie " ,
101+ " -shared " ,
76102 " --import-memory" ,
77- " --no-entry" ,
78- " --export-all" ,
79103 " --experimental-pic" ,
80- " --no-export-dynamic" ,
81104 " --stack-first" ,
82- OutputFileName.c_str (),
105+ " --allow-undefined" ,
106+ ObjectFileName.c_str (),
83107 " -o" ,
84- OutputFileName.c_str ()};
85- int Result =
86- lld::wasm::link (LinkerArgs, llvm::outs (), llvm::errs (), false , false );
87- if (!Result)
108+ BinaryFileName.c_str ()};
109+
110+ const lld::DriverDef WasmDriver = {lld::Flavor::Wasm, &lld::wasm::link};
111+ std::vector<lld::DriverDef> WasmDriverArgs;
112+ WasmDriverArgs.push_back (WasmDriver);
113+ lld::Result Result =
114+ lld::lldMain (LinkerArgs, llvm::outs (), llvm::errs (), WasmDriverArgs);
115+
116+ if (Result.retCode )
88117 return llvm::make_error<llvm::StringError>(
89118 " Failed to link incremental module" , llvm::inconvertibleErrorCode ());
90119
91120 void *LoadedLibModule =
92- dlopen (OutputFileName .c_str (), RTLD_NOW | RTLD_GLOBAL);
121+ dlopen (BinaryFileName .c_str (), RTLD_NOW | RTLD_GLOBAL);
93122 if (LoadedLibModule == nullptr ) {
94123 llvm::errs () << dlerror () << ' \n ' ;
95124 return llvm::make_error<llvm::StringError>(
@@ -109,6 +138,12 @@ llvm::Error WasmIncrementalExecutor::runCtors() const {
109138 return llvm::Error::success ();
110139}
111140
141+ llvm::Error WasmIncrementalExecutor::cleanUp () {
142+ // Can't call cleanUp through IncrementalExecutor as it
143+ // tries to deinitialize JIT which hasn't been initialized
144+ return llvm::Error::success ();
145+ }
146+
112147WasmIncrementalExecutor::~WasmIncrementalExecutor () = default ;
113148
114- } // namespace clang
149+ } // namespace clang
0 commit comments