https://github.com/anutosh491 created https://github.com/llvm/llvm-project/pull/117978
None >From 987f77db9d45dee264c60f434652131438784f6f Mon Sep 17 00:00:00 2001 From: anutosh491 <andersonbhat...@gmail.com> Date: Thu, 28 Nov 2024 14:02:00 +0530 Subject: [PATCH] Fix generation of wasm binaries while running clang-repl in browser --- clang/lib/Interpreter/CMakeLists.txt | 2 + clang/lib/Interpreter/Interpreter.cpp | 1 + clang/lib/Interpreter/Wasm.cpp | 57 ++++++++++++++++++++------- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index df7ea82e0dada5..bf70cdfbee01e1 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -16,6 +16,7 @@ set(LLVM_LINK_COMPONENTS if (EMSCRIPTEN AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) set(WASM_SRC Wasm.cpp) set(WASM_LINK lldWasm) + set(COMMON_LINK lldCommon) endif() add_clang_library(clangInterpreter @@ -47,6 +48,7 @@ add_clang_library(clangInterpreter clangSema clangSerialization ${WASM_LINK} + ${COMMON_LINK} ) if ((MINGW OR CYGWIN) AND BUILD_SHARED_LIBS) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 5dc67f6375098f..887b494ff98f19 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -201,6 +201,7 @@ IncrementalCompilerBuilder::CreateCpp() { Argv.push_back("-target"); Argv.push_back("wasm32-unknown-emscripten"); Argv.push_back("-shared"); + Argv.push_back("-fvisibility=default"); #endif Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp index 79efbaa03982d0..0fd6ad509c2938 100644 --- a/clang/lib/Interpreter/Wasm.cpp +++ b/clang/lib/Interpreter/Wasm.cpp @@ -23,6 +23,31 @@ #include <string> namespace lld { +enum Flavor { + Invalid, + Gnu, // -flavor gnu + MinGW, // -flavor gnu MinGW + WinLink, // -flavor link + Darwin, // -flavor darwin + Wasm, // -flavor wasm +}; + +using Driver = bool (*)(llvm::ArrayRef<const char *>, llvm::raw_ostream &, + llvm::raw_ostream &, bool, bool); + +struct DriverDef { + Flavor f; + Driver d; +}; + +struct Result { + int retCode; + bool canRunAgain; +}; + +Result lldMain(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, + llvm::raw_ostream &stderrOS, llvm::ArrayRef<DriverDef> drivers); + namespace wasm { bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); @@ -51,45 +76,47 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) { llvm::TargetMachine *TargetMachine = Target->createTargetMachine( PTU.TheModule->getTargetTriple(), "", "", TO, llvm::Reloc::Model::PIC_); PTU.TheModule->setDataLayout(TargetMachine->createDataLayout()); - std::string OutputFileName = PTU.TheModule->getName().str() + ".wasm"; + std::string ObjectFileName = PTU.TheModule->getName().str() + ".o"; // For the wasm object + std::string BinaryFileName = PTU.TheModule->getName().str() + ".wasm"; // For the wasm binary std::error_code Error; - llvm::raw_fd_ostream OutputFile(llvm::StringRef(OutputFileName), Error); + llvm::raw_fd_ostream ObjectFileOutput(llvm::StringRef(ObjectFileName), Error); llvm::legacy::PassManager PM; - if (TargetMachine->addPassesToEmitFile(PM, OutputFile, nullptr, + if (TargetMachine->addPassesToEmitFile(PM, ObjectFileOutput, nullptr, llvm::CodeGenFileType::ObjectFile)) { return llvm::make_error<llvm::StringError>( "Wasm backend cannot produce object.", llvm::inconvertibleErrorCode()); } if (!PM.run(*PTU.TheModule)) { - return llvm::make_error<llvm::StringError>("Failed to emit Wasm object.", llvm::inconvertibleErrorCode()); } - OutputFile.close(); + ObjectFileOutput.close(); std::vector<const char *> LinkerArgs = {"wasm-ld", "-shared", "--import-memory", - "--no-entry", - "--export-all", "--experimental-pic", "--stack-first", "--allow-undefined", - OutputFileName.c_str(), + ObjectFileName.c_str(), "-o", - OutputFileName.c_str()}; - int Result = - lld::wasm::link(LinkerArgs, llvm::outs(), llvm::errs(), false, false); - if (!Result) + BinaryFileName.c_str()}; + + const lld::DriverDef WasmDriver = {lld::Flavor::Wasm, &lld::wasm::link}; + std::vector<lld::DriverDef> WasmDriverArgs; + WasmDriverArgs.push_back(WasmDriver); + lld::Result Result = lld::lldMain(LinkerArgs, llvm::outs(), llvm::errs(), WasmDriverArgs); + + if (Result.retCode != 0) return llvm::make_error<llvm::StringError>( "Failed to link incremental module", llvm::inconvertibleErrorCode()); void *LoadedLibModule = - dlopen(OutputFileName.c_str(), RTLD_NOW | RTLD_GLOBAL); + dlopen(BinaryFileName.c_str(), RTLD_NOW | RTLD_GLOBAL); if (LoadedLibModule == nullptr) { llvm::errs() << dlerror() << '\n'; return llvm::make_error<llvm::StringError>( @@ -109,7 +136,7 @@ llvm::Error WasmIncrementalExecutor::runCtors() const { return llvm::Error::success(); } -llvm::Error WasmIncrementalExecutor::cleanUp() const { +llvm::Error WasmIncrementalExecutor::cleanUp() { // Can't call cleanUp through IncrementalExecutor as it // tries to deinitialize JIT which hasn't been initialized return llvm::Error::success(); @@ -117,4 +144,4 @@ llvm::Error WasmIncrementalExecutor::cleanUp() const { WasmIncrementalExecutor::~WasmIncrementalExecutor() = default; -} // namespace clang +} // namespace clang \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits