22
33#include " clang/Interpreter/CppInterOp.h"
44
5+
6+ #include " llvm/ExecutionEngine/Orc/Core.h"
7+ #include " llvm/ExecutionEngine/Orc/DebugUtils.h"
58#include " llvm/Support/FileSystem.h"
69#include " llvm/Support/Path.h"
7-
10+ # include " llvm/Support/raw_ostream.h "
811
912// Helper functions
1013
1316// GetMainExecutable (since some platforms don't support taking the
1417// address of main, and some platforms can't implement GetMainExecutable
1518// without being given the address of a function in the main executable).
16- std::string GetExecutablePath (const char * Argv0) {
19+ std::string GetExecutablePath (const char * Argv0, void * mainAddr = nullptr ) {
1720 // This just needs to be some symbol in the binary; C++ doesn't
1821 // allow taking the address of ::main however.
19- void * MainAddr = (void *)intptr_t (GetExecutablePath);
22+ void * MainAddr = mainAddr ? mainAddr : (void *)intptr_t (GetExecutablePath);
2023 return llvm::sys::fs::getMainExecutable (Argv0, MainAddr);
2124}
2225
26+ // Mangle symbol name
2327static inline std::string MangleNameForDlsym (const std::string& name) {
2428 std::string nameForDlsym = name;
2529#if defined(R__MACOSX) || defined(R__WIN32)
@@ -29,30 +33,33 @@ static inline std::string MangleNameForDlsym(const std::string& name) {
2933 return nameForDlsym;
3034}
3135
36+ #include " ../../lib/Interpreter/CppInterOp.cpp"
37+
38+
3239// Tests
3340
3441TEST (DynamicLibraryManagerTest, Sanity) {
3542 EXPECT_TRUE (Cpp::CreateInterpreter ());
3643 EXPECT_FALSE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_zero" ).c_str ()));
3744
38- std::string BinaryPath = GetExecutablePath (/* Argv0= */ nullptr );
45+ std::string BinaryPath = GetExecutablePath (nullptr , nullptr );
3946 llvm::StringRef Dir = llvm::sys::path::parent_path (BinaryPath);
4047 Cpp::AddSearchPath (Dir.str ().c_str ());
4148
49+ // Find and load library with "ret_zero" symbol defined and exported
50+ //
4251 // FIXME: dlsym on mach-o takes the C-level name, however, the macho-o format
4352 // adds an additional underscore (_) prefix to the lowered names. Figure out
4453 // how to harmonize that API.
45-
4654 std::string PathToTestSharedLib =
4755 Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_zero" ).c_str (), /* system_search=*/ false );
48-
4956 EXPECT_STRNE (" " , PathToTestSharedLib.c_str ())
50- << " Cannot find: '" << PathToTestSharedLib << " ' in '" << Dir.str ()
51- << " '" ;
52-
57+ << " Cannot find: '" << PathToTestSharedLib << " ' in '" << Dir.str () << " '" ;
5358 EXPECT_TRUE (Cpp::LoadLibrary (PathToTestSharedLib.c_str ()));
59+
5460 // Force ExecutionEngine to be created.
5561 Cpp::Process (" " );
62+
5663 // FIXME: Conda returns false to run this code on osx.
5764 EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_zero" ).c_str ()));
5865
@@ -70,19 +77,18 @@ TEST(DynamicLibraryManagerTest, LibrariesAutoload) {
7077 EXPECT_FALSE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_one" ).c_str ()));
7178
7279 // Libraries Search path by default is set to main executable directory.
73- std::string BinaryPath = GetExecutablePath (/* Argv0= */ nullptr );
80+ std::string BinaryPath = GetExecutablePath (nullptr , nullptr );
7481 llvm::StringRef Dir = llvm::sys::path::parent_path (BinaryPath);
7582 Cpp::AddSearchPath (Dir.str ().c_str ());
7683
77- // Find library with "rec_one " symbol defined and exported
84+ // Find library with "ret_one " symbol defined and exported
7885 //
7986 // FIXME: dlsym on mach-o takes the C-level name, however, the macho-o format
8087 // adds an additional underscore (_) prefix to the lowered names. Figure out
8188 // how to harmonize that API. For now we use out minimal implementation of
8289 // helper function.
8390 std::string PathToTestSharedLib1 =
8491 Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_one" ).c_str (), /* system_search=*/ false );
85-
8692 // If result is "" then we cannot find this library.
8793 EXPECT_STRNE (" " , PathToTestSharedLib1.c_str ())
8894 << " Cannot find: '" << PathToTestSharedLib1 << " ' in '" << Dir.str () << " '" ;
@@ -117,13 +123,95 @@ TEST(DynamicLibraryManagerTest, LibrariesAutoload) {
117123 Cpp::SetLibrariesAutoload (false );
118124 // Check autorum status (must be turned OFF)
119125 EXPECT_FALSE (Cpp::GetLibrariesAutoload ());
120- // EXPECT_FALSE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str())); // if unload works
121- // EXPECT_TRUE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str()));
126+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_one" ).c_str ())); // false if unload works
122127
123128 // Autoload turn ON again
124129 Cpp::SetLibrariesAutoload (true );
125130 // Check autorum status (must be turned ON)
126131 EXPECT_TRUE (Cpp::GetLibrariesAutoload ());
127- // EXPECT_FALSE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str())); // if unload works
128- // EXPECT_TRUE(Cpp::GetFunctionAddress(MangleNameForDlsym("ret_one").c_str()));
132+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_one" ).c_str ()));
133+
134+ // Find library with "ret_1" symbol defined and exported
135+ std::string PathToTestSharedLib2 =
136+ Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_1" ).c_str (), /* system_search=*/ false );
137+ // If result is "" then we cannot find this library.
138+ EXPECT_STRNE (" " , PathToTestSharedLib2.c_str ())
139+ << " Cannot find: '" << PathToTestSharedLib2 << " ' in '" << Dir.str () << " '" ;
140+ // Find symbol must success (when auotload=on)
141+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_1" ).c_str ()));
142+ // Find symbol must success (when auotload=on)
143+ EXPECT_TRUE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_2" ).c_str ()));
144+ }
145+
146+ TEST (DynamicLibraryManagerTest, LibrariesAutoloadExtraCoverage) {
147+ EXPECT_TRUE (Cpp::CreateInterpreter ());
148+
149+ // Libraries Search path by default is set to main executable directory.
150+ std::string BinaryPath = GetExecutablePath (nullptr , nullptr );
151+ llvm::StringRef Dir = llvm::sys::path::parent_path (BinaryPath);
152+ Cpp::AddSearchPath (Dir.str ().c_str ());
153+
154+ // Force ExecutionEngine to be created.
155+ Cpp::Process (" " );
156+
157+ // Autoload turn ON
158+ Cpp::SetLibrariesAutoload (true );
159+ // Check autorum status (must be turned ON)
160+ EXPECT_TRUE (Cpp::GetLibrariesAutoload ());
161+
162+ // Cover: MU getName()
163+ std::string res;
164+ llvm::raw_string_ostream rss (res);
165+ const llvm::orc::SymbolNameVector syms;
166+ Cpp::AutoLoadLibrarySearchGenerator::AutoloadLibraryMU MU (" test" , syms);
167+ rss << MU;
168+ EXPECT_STRNE (" " , rss.str ().c_str ()) << " MU problem!" ;
169+
170+ // Cover: LoadLibrary error
171+ // if (DLM->loadLibrary(lib, false) != DynamicLibraryManager::LoadLibResult::kLoadLibSuccess) {
172+ // LLVM_DEBUG(dbgs() << "MU: Failed to load library " << lib);
173+ // string err = "MU: Failed to load library! " + lib;
174+ // perror(err.c_str());
175+ // } else {
176+ // Find library with "ret_value" symbol defined and exported
177+ std::string PathToTestSharedLib3 =
178+ Cpp::SearchLibrariesForSymbol (MangleNameForDlsym (" ret_val" ).c_str (), /* system_search=*/ false );
179+ // If result is "" then we cannot find this library.
180+ EXPECT_STRNE (" " , PathToTestSharedLib3.c_str ())
181+ << " Cannot find: '" << PathToTestSharedLib3 << " ' in '" << Dir.str () << " '" ;
182+ // Remove library for simulate load error
183+ llvm::sys::fs::remove (PathToTestSharedLib3, true );
184+ EXPECT_TRUE (Cpp::GetLibrariesAutoload ());
185+ // FIXME: Conda returns false to run this code on osx.
186+ EXPECT_FALSE (Cpp::GetFunctionAddress (MangleNameForDlsym (" ret_val" ).c_str ()));
187+
188+ // Cover
189+ // } else {
190+ // // Collect all failing symbols, delegate their responsibility and then
191+ // // fail their materialization. R->defineNonExistent() sounds like it
192+ // // should do that, but it's not implemented?!
193+ // failedSymbols.insert(symbol);
194+ // TODO: implement test this case
195+
196+ // Cover
197+ // if (!failedSymbols.empty()) {
198+ // auto failingMR = R->delegate(failedSymbols);
199+ // if (failingMR) {
200+ // (*failingMR)->failMaterialization();
201+ // TODO: implement test this case
202+
203+ // Cover
204+ // void discard(const llvm::orc::JITDylib &JD, const llvm::orc::SymbolStringPtr &Name) override {}
205+ // TODO: implement test this case
206+
207+ // Cover
208+ // if (Path.empty()) {
209+ // LLVM_DEBUG(dbgs() << "DynamicLibraryManager::lookupLibMaybeAddExt(): "
210+ // TODO: implement test this case
211+
212+ // Cover
213+ // platform::DLClose(dyLibHandle, &errMsg);
214+ // if (!errMsg.empty()) {
215+ // LLVM_DEBUG(dbgs() << "DynamicLibraryManager::unloadLibrary(): "
216+ // TODO: implement test this case
129217}
0 commit comments