Skip to content

Commit a174aa1

Browse files
[clang-repl] Fix generation of wasm binaries while running clang-repl in browser (llvm#117978)
Co-authored-by: Vassil Vassilev <[email protected]>
1 parent ed7f36e commit a174aa1

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

clang/lib/Interpreter/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ set(LLVM_LINK_COMPONENTS
1616
if (EMSCRIPTEN AND "lld" IN_LIST LLVM_ENABLE_PROJECTS)
1717
set(WASM_SRC Wasm.cpp)
1818
set(WASM_LINK lldWasm)
19+
set(COMMON_LINK lldCommon)
1920
endif()
2021

2122
add_clang_library(clangInterpreter
@@ -47,6 +48,7 @@ add_clang_library(clangInterpreter
4748
clangSema
4849
clangSerialization
4950
${WASM_LINK}
51+
${COMMON_LINK}
5052
)
5153

5254
if ((MINGW OR CYGWIN) AND BUILD_SHARED_LIBS)

clang/lib/Interpreter/Interpreter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ IncrementalCompilerBuilder::CreateCpp() {
201201
Argv.push_back("-target");
202202
Argv.push_back("wasm32-unknown-emscripten");
203203
Argv.push_back("-shared");
204+
Argv.push_back("-fvisibility=default");
204205
#endif
205206
Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
206207

clang/lib/Interpreter/Wasm.cpp

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,31 @@
2323
#include <string>
2424

2525
namespace 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+
2651
namespace wasm {
2752
bool 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",
75101
"-shared",
76102
"--import-memory",
77-
"--no-entry",
78-
"--export-all",
79103
"--experimental-pic",
80104
"--stack-first",
81105
"--allow-undefined",
82-
OutputFileName.c_str(),
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,12 +138,12 @@ llvm::Error WasmIncrementalExecutor::runCtors() const {
109138
return llvm::Error::success();
110139
}
111140

112-
llvm::Error WasmIncrementalExecutor::cleanUp() const {
141+
llvm::Error WasmIncrementalExecutor::cleanUp() {
113142
// Can't call cleanUp through IncrementalExecutor as it
114143
// tries to deinitialize JIT which hasn't been initialized
115144
return llvm::Error::success();
116145
}
117146

118147
WasmIncrementalExecutor::~WasmIncrementalExecutor() = default;
119148

120-
} // namespace clang
149+
} // namespace clang

0 commit comments

Comments
 (0)