From: levill_r <levill_r@4aad255d-cdde-0310-9447-f3009e2ae8c0>
* src/function_loader.cc (dyn::function_loader_t::cxx_load):
New method.
git-svn-id:
https://svn.lrde.epita.fr/svn/oln/trunk@4664
4aad255d-cdde-0310-9447-f3009e2ae8c0
---
dynamic-use-of-static-c++/ChangeLog | 7 ++
dynamic-use-of-static-c++/src/function_loader.cc | 90 ++++++++++++++++++++++
2 files changed, 97 insertions(+), 0 deletions(-)
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index cd807af..89224a7 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -1,5 +1,12 @@
2009-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+ Provide a C++ implementation of the dynamic function loader.
+
+ * src/function_loader.cc (dyn::function_loader_t::cxx_load):
+ New method.
+
+2009-10-22 Roland Levillain <roland(a)lrde.epita.fr>
+
Have libdyn depend on libmd5.
* src/Makefile.am (libdyn_la_LIBADD): Add
diff --git a/dynamic-use-of-static-c++/src/function_loader.cc
b/dynamic-use-of-static-c++/src/function_loader.cc
index 863452c..113213a 100644
--- a/dynamic-use-of-static-c++/src/function_loader.cc
+++ b/dynamic-use-of-static-c++/src/function_loader.cc
@@ -12,6 +12,8 @@
# include <boost/filesystem/fstream.hpp>
# include <boost/algorithm/string/replace.hpp>
+# include "md5.hh"
+
# include "data.hh"
# include "function_loader.hh"
# include "ruby_stream.hh"
@@ -403,6 +405,94 @@ namespace dyn {
return ptr;
}
+ // FIXME: This C++ version of load shares a lot with the latter.
+ void*
+ cxx_load(fun_kind kind,
+ const std::string& name,
+ const arguments_types_t& arguments_types,
+ const std::string& paths)
+ {
+ std::ostringstream ostr;
+ ostr << name << '(';
+ arguments_types_t::const_iterator it(arguments_types.begin());
+ if (it != arguments_types.end())
+ {
+ ostr << *it;
+ for (++it; it != arguments_types.end(); ++it)
+ ostr << ", " << *it;
+ }
+ ostr << ')';
+ if (paths != "")
+ {
+ ostr << ", paths: ";
+ gen_path<std::ostream> fun(ostr);
+ foreach_path_in_paths(paths, fun);
+ }
+ std::string prototype = ostr.str();
+
+ // FIXME: Careful, this cast removes a const! We should improve
+ // the interface of libmd5.
+ std::string identifier(MD5((unsigned char*)prototype.c_str()).hex_digest());
+
+ cache_type::iterator ptr_it = cache.find(identifier.c_str());
+
+ // FIXME: It seems the cache doesn't work at all (we almost
+ // never hit). See why this is happening.
+ if (ptr_it != cache.end())
+ {
+ // FIXME: Colors should be used only when the terminal supports them.
+#if 0
+ std::cerr << "\e[36mJIT: \e[32mHIT: \e[0m " << prototype
<< std::endl;
+#endif
+ std::cerr << "JIT: HIT: " << prototype <<
std::endl;
+ return ptr_it->second;
+ }
+
+ // FIXME: Colors should be used only when the terminal supports them.
+#if 0
+ std::cerr << "\e[36mJIT: \e[31mMISS: compile: \e[0m " <<
prototype << std::endl;
+#endif
+ std::cerr << "JIT: MISS: compile: " << prototype <<
std::endl;
+
+ std::ostringstream cxx;
+ gen_cxx(identifier, name, arguments_types, kind, paths, cxx);
+ // FIXME: Rename cflags_ as cxxflags_.
+ /* FIXME: The interface of join is not elegant. I'd prefer to write
+
+ std::stringstream cflags_stream;
+ cflags_stream << join(cflags_.begin(), cflags_.end(), ' ');
+
+ or even
+
+ std::string cflags_string =
+ join(cflags_.begin(), cflags_.end(), ' ');
+
+ But doesn't Boost propose this? E.g. :
+
+ std::string cflags = ba::string::join(cflags_, ' ');
+
+ ? */
+ std::stringstream cflags_stream;
+ join(cflags_.begin(), cflags_.end(), ' ', cflags_stream);
+ std::stringstream ldflags_stream;
+ join(ldflags_.begin(), ldflags_.end(), ' ', ldflags_stream);
+
+ cxx_compile(cxx.str(), identifier,
+ cflags_stream.str(), ldflags_stream.str());
+
+ const char* error;
+ std::string lib_path = std::string("repository/") + identifier
+ + "/libdyn_" + identifier + ".la";
+ std::string symb = std::string("dyn_") + identifier;
+
+ lt_dlhandle lib = lt_dlopen(lib_path.c_str());
+ if ((error = lt_dlerror())) std::cerr << error << std::endl;
+ void* ptr = lt_dlsym(lib, symb.c_str());
+ cache[identifier.c_str()] = ptr;
+ if ((error = lt_dlerror())) std::cerr << error << std::endl;
+ return ptr;
+ }
+
protected:
typedef std::map<const char*, void*, ltstr> cache_type;
cache_type cache;
--
1.6.5