Skip to content

Commit 8f56394

Browse files
authored
[clang-repl] Implement LoadDynamicLibrary for clang-repl wasm use cases (#133037)
**Currently we don't make use of the JIT for the wasm use cases so the approach using the execution engine won't work in these cases.** Rather if we use dlopen. We should be able to do the following (demonstrating through a toy project) 1) Make use of LoadDynamicLibrary through the given implementation ``` extern "C" EMSCRIPTEN_KEEPALIVE int load_library(const char *name) { auto Err = Interp->LoadDynamicLibrary(name); if (Err) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "load_library error: "); return -1; } return 0; } ``` 2) Add a button to call load_library once the library has been added in our MEMFS (currently we have symengine built as a SIDE MODULE and we are loading it)
1 parent c192737 commit 8f56394

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

clang/lib/Interpreter/IncrementalExecutor.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ class IncrementalExecutor {
5757
virtual llvm::Error removeModule(PartialTranslationUnit &PTU);
5858
virtual llvm::Error runCtors() const;
5959
virtual llvm::Error cleanUp();
60-
llvm::Expected<llvm::orc::ExecutorAddr>
60+
virtual llvm::Expected<llvm::orc::ExecutorAddr>
6161
getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const;
6262

6363
llvm::orc::LLJIT &GetExecutionEngine() { return *Jit; }

clang/lib/Interpreter/Interpreter.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/Support/VirtualFileSystem.h"
1919
#ifdef __EMSCRIPTEN__
2020
#include "Wasm.h"
21+
#include <dlfcn.h>
2122
#endif // __EMSCRIPTEN__
2223

2324
#include "clang/AST/ASTConsumer.h"
@@ -711,6 +712,14 @@ llvm::Error Interpreter::Undo(unsigned N) {
711712
}
712713

713714
llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
715+
#ifdef __EMSCRIPTEN__
716+
void *handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
717+
if (!handle) {
718+
llvm::errs() << dlerror() << '\n';
719+
return llvm::make_error<llvm::StringError>("Failed to load dynamic library",
720+
llvm::inconvertibleErrorCode());
721+
}
722+
#else
714723
auto EE = getExecutionEngine();
715724
if (!EE)
716725
return EE.takeError();
@@ -722,6 +731,7 @@ llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
722731
EE->getMainJITDylib().addGenerator(std::move(*DLSG));
723732
else
724733
return DLSG.takeError();
734+
#endif
725735

726736
return llvm::Error::success();
727737
}

clang/lib/Interpreter/Wasm.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,19 @@ llvm::Error WasmIncrementalExecutor::cleanUp() {
144144
return llvm::Error::success();
145145
}
146146

147+
llvm::Expected<llvm::orc::ExecutorAddr>
148+
WasmIncrementalExecutor::getSymbolAddress(llvm::StringRef Name,
149+
SymbolNameKind NameKind) const {
150+
void *Sym = dlsym(RTLD_DEFAULT, Name.str().c_str());
151+
if (!Sym) {
152+
return llvm::make_error<llvm::StringError>("dlsym failed for symbol: " +
153+
Name.str(),
154+
llvm::inconvertibleErrorCode());
155+
}
156+
157+
return llvm::orc::ExecutorAddr::fromPtr(Sym);
158+
}
159+
147160
WasmIncrementalExecutor::~WasmIncrementalExecutor() = default;
148161

149162
} // namespace clang

clang/lib/Interpreter/Wasm.h

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class WasmIncrementalExecutor : public IncrementalExecutor {
2929
llvm::Error removeModule(PartialTranslationUnit &PTU) override;
3030
llvm::Error runCtors() const override;
3131
llvm::Error cleanUp() override;
32+
llvm::Expected<llvm::orc::ExecutorAddr>
33+
getSymbolAddress(llvm::StringRef Name,
34+
SymbolNameKind NameKind) const override;
3235

3336
~WasmIncrementalExecutor() override;
3437
};

0 commit comments

Comments
 (0)