Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 8 additions & 101 deletions core/metacling/src/TCling.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -6501,14 +6501,18 @@ bool TCling::LibraryLoadingFailed(const std::string& errmessage, const std::stri
return false;
}

static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_name,
const cling::DynamicLibraryManager &DLM) {
////////////////////////////////////////////////////////////////////////////////
/// Autoload a library based on a missing symbol.

void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {

const cling::DynamicLibraryManager &DLM = *GetInterpreterImpl()->getDynamicLibraryManager();
R__LOCKGUARD(gInterpreterMutex);

auto LibLoader = [](const std::string& LibName) -> bool {
if (gSystem->Load(LibName.c_str(), "", false) < 0) {
Error("TCling__LazyFunctionCreatorAutoloadForModule",
"Failed to load library %s", LibName.c_str());
::Error("TCling__LazyFunctionCreatorAutoloadForModule",
"Failed to load library %s", LibName.c_str());
return false;
}
return true; //success.
Expand Down Expand Up @@ -6536,103 +6540,6 @@ static void* LazyFunctionCreatorAutoloadForModule(const std::string &mangled_nam
return nullptr;

return llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name);

}

////////////////////////////////////////////////////////////////////////////////
/// Autoload a library based on a missing symbol.

void* TCling::LazyFunctionCreatorAutoload(const std::string& mangled_name) {
if (fCxxModulesEnabled)
return LazyFunctionCreatorAutoloadForModule(mangled_name,
*GetInterpreterImpl()->getDynamicLibraryManager());

// First see whether the symbol is in the library that we are currently
// loading. It will have access to the symbols of its dependent libraries,
// thus checking "back()" is sufficient.
if (!fRegisterModuleDyLibs.empty()) {
if (void* addr = dlsym(fRegisterModuleDyLibs.back(),
mangled_name.c_str())) {
return addr;
}
}

int err = 0;
char* demangled_name_c = TClassEdit::DemangleName(mangled_name.c_str(), err);
if (err) {
return 0;
}

std::string name(demangled_name_c);
free(demangled_name_c);

//fprintf(stderr, "demangled name: '%s'\n", demangled_name);
//
// Separate out the class or namespace part of the
// function name.
//

std::string::size_type pos = name.find("__thiscall ");
if (pos != std::string::npos) {
name.erase(0, pos + sizeof("__thiscall ")-1);
}
pos = name.find("__cdecl ");
if (pos != std::string::npos) {
name.erase(0, pos + sizeof("__cdecl ")-1);
}
if (!strncmp(name.c_str(), "typeinfo for ", sizeof("typeinfo for ")-1)) {
name.erase(0, sizeof("typeinfo for ")-1);
} else if (!strncmp(name.c_str(), "vtable for ", sizeof("vtable for ")-1)) {
name.erase(0, sizeof("vtable for ")-1);
} else if (!strncmp(name.c_str(), "operator", sizeof("operator")-1)
&& !isalnum(name[sizeof("operator")])) {
// operator...(A, B) - let's try with A!
name.erase(0, sizeof("operator")-1);
pos = name.rfind('(');
if (pos != std::string::npos) {
name.erase(0, pos + 1);
pos = name.find(",");
if (pos != std::string::npos) {
// remove next arg up to end, leaving only the first argument type.
name.erase(pos);
}
pos = name.rfind(" const");
if (pos != std::string::npos) {
name.erase(pos, strlen(" const"));
}
while (!name.empty() && strchr("&*", name.back()))
name.erase(name.length() - 1);
}
} else {
TClassEdit::FunctionSplitInfo fsi;
TClassEdit::SplitFunction(name, fsi);
name = fsi.fScopeName;
}
//fprintf(stderr, "name: '%s'\n", name.c_str());
// Now we have the class or namespace name, so do the lookup.
TString libs = GetClassSharedLibs(name.c_str());
if (libs.IsNull()) {
// Not found in the map, all done.
return 0;
}
//fprintf(stderr, "library: %s\n", iter->second.c_str());
// Now we have the name of the libraries to load, so load them.

TString lib;
Ssiz_t posLib = 0;
while (libs.Tokenize(lib, posLib)) {
if (gSystem->Load(lib, "", kFALSE /*system*/) < 0) {
// The library load failed, all done.
//fprintf(stderr, "load failed: %s\n", errmsg.c_str());
return 0;
}
}

//fprintf(stderr, "load succeeded.\n");
// Get the address of the function being called.
void* addr = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(mangled_name.c_str());
//fprintf(stderr, "addr: %016lx\n", reinterpret_cast<unsigned long>(addr));
return addr;
}

////////////////////////////////////////////////////////////////////////////////
Expand Down