From 4ebfe264e98ee393d1a1af50d6c80ee1019434a7 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sun, 3 Jun 2012 08:11:37 -0600 Subject: [PATCH] Make stdlib * Build the standard library as a module .so * Locate and load lib at runtime as a module if it is not provided to the ChaiScript constructor. Decreases compile time by 1/2 for common use cases where the user can use the dynamic library module. --- CMakeLists.txt | 4 ++ include/chaiscript/chaiscript.hpp | 8 +-- include/chaiscript/chaiscript_defines.hpp | 8 +++ include/chaiscript/chaiscript_stdlib.hpp | 1 + .../chaiscript/language/chaiscript_engine.hpp | 70 ++++++++++++++++++- src/main.cpp | 3 +- 6 files changed, 85 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b6f765c..1d30e69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,8 +103,12 @@ if (CMAKE_COMPILER_2005) # ADD_DEFINITIONS(/wd4244) endif() +add_library(chaiscript_stdlib MODULE src/chaiscript_stdlib.cpp) +target_link_libraries(chaiscript_stdlib ${LIBS} ${EXTRA_LINKER_FLAGS}) + add_executable(chai src/main.cpp ${Chai_INCLUDES}) target_link_libraries(chai ${LIBS} ${EXTRA_LINKER_FLAGS}) +add_dependencies(chai chaiscript_stdlib) if (BUILD_SAMPLES) add_executable(example samples/example.cpp) diff --git a/include/chaiscript/chaiscript.hpp b/include/chaiscript/chaiscript.hpp index 11a013a..380b6eb 100644 --- a/include/chaiscript/chaiscript.hpp +++ b/include/chaiscript/chaiscript.hpp @@ -752,13 +752,9 @@ #include "dispatchkit/dynamic_object.hpp" #include "dispatchkit/boxed_number.hpp" -#ifdef CHAISCRIPT_HAS_DECLSPEC -#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport) -#else -#define CHAISCRIPT_MODULE_EXPORT extern "C" -#endif - #include "language/chaiscript_eval.hpp" #include "language/chaiscript_engine.hpp" + + #endif /* CHAISCRIPT_HPP_ */ diff --git a/include/chaiscript/chaiscript_defines.hpp b/include/chaiscript/chaiscript_defines.hpp index 162454c..de6aeb9 100644 --- a/include/chaiscript/chaiscript_defines.hpp +++ b/include/chaiscript/chaiscript_defines.hpp @@ -16,5 +16,13 @@ #define CHAISCRIPT_WINDOWS #endif + +#ifdef CHAISCRIPT_HAS_DECLSPEC +#define CHAISCRIPT_MODULE_EXPORT extern "C" __declspec(dllexport) +#else +#define CHAISCRIPT_MODULE_EXPORT extern "C" +#endif + + #endif diff --git a/include/chaiscript/chaiscript_stdlib.hpp b/include/chaiscript/chaiscript_stdlib.hpp index 8f4bafa..0fdad69 100644 --- a/include/chaiscript/chaiscript_stdlib.hpp +++ b/include/chaiscript/chaiscript_stdlib.hpp @@ -7,6 +7,7 @@ #ifndef CHAISCRIPT_STDLIB_HPP_ #define CHAISCRIPT_STDLIB_HPP_ +#include "chaiscript_defines.hpp" #include "dispatchkit/bootstrap.hpp" #include "dispatchkit/bootstrap_stl.hpp" diff --git a/include/chaiscript/language/chaiscript_engine.hpp b/include/chaiscript/language/chaiscript_engine.hpp index c9dd0bd..77d5fe0 100644 --- a/include/chaiscript/language/chaiscript_engine.hpp +++ b/include/chaiscript/language/chaiscript_engine.hpp @@ -325,7 +325,10 @@ namespace chaiscript m_engine.add_reserved_word("false"); m_engine.add_reserved_word("_"); - add(t_lib); + if (t_lib) + { + add(t_lib); + } m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_system, std::ref(m_engine)), "dump_system"); m_engine.add(fun(&chaiscript::detail::Dispatch_Engine::dump_object, std::ref(m_engine)), "dump_object"); @@ -399,6 +402,71 @@ namespace chaiscript build_eval_system(t_lib); } + /// \brief Constructor for ChaiScript. + /// + /// This version of the ChaiScript constructor attempts to find the stdlib module to load + /// at runtime generates an error if it cannot be found. + /// + /// \param[in] t_modulepaths Vector of paths to search when attempting to load a binary module + /// \param[in] t_usepaths Vector of paths to search when attempting to "use" an included ChaiScript file + ChaiScript( const std::vector &t_modulepaths = std::vector(), + const std::vector &t_usepaths = std::vector()) + : m_modulepaths(t_modulepaths), m_usepaths(t_usepaths) + { + if (m_modulepaths.empty()) + { + m_modulepaths.push_back(""); + } + + if (m_usepaths.empty()) + { + m_usepaths.push_back(""); + } + + +#ifdef _POSIX_VERSION + // If on Unix, add the path of the current executable to the module search path + // as windows would do + + union cast_union + { + void (ChaiScript::*in_ptr)(const std::string&); + void *out_ptr; + }; + + Dl_info rInfo; + memset( &rInfo, 0, sizeof(rInfo) ); + cast_union u; + u.in_ptr = &ChaiScript::use; + if ( dladdr((void*)(u.out_ptr), &rInfo) && rInfo.dli_fname ) { + std::string dllpath(rInfo.dli_fname); + size_t lastslash = dllpath.rfind('/'); + if (lastslash != std::string::npos) + { + dllpath.erase(lastslash); + } + + // Let's see if this is a link that we should expand + std::vector buf(2048); + size_t pathlen = readlink(dllpath.c_str(), &buf.front(), buf.size()); + if (pathlen > 0 && pathlen < buf.size()) + { + dllpath = std::string(&buf.front(), pathlen); + } + + m_modulepaths.push_back(dllpath+"/"); + } +#endif + + + // attempt to load the stdlib + load_module("chaiscript_stdlib"); + + build_eval_system(ModulePtr()); + } + + + /// \brief Loads and parses a file. If the file is already, it is not reloaded /// The use paths specified at ChaiScript construction time are searched for the /// requested file. diff --git a/src/main.cpp b/src/main.cpp index c990374..74917a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,6 @@ #define _CRT_SECURE_NO_WARNINGS #include -#include #ifdef READLINE_AVAILABLE #include @@ -177,7 +176,7 @@ int main(int argc, char *argv[]) modulepaths.push_back(modulepath); } - chaiscript::ChaiScript chai(chaiscript::Std_Lib::library(), modulepaths,usepaths); + chaiscript::ChaiScript chai(modulepaths,usepaths); chai.add(chaiscript::fun(&myexit), "exit"); chai.add(chaiscript::fun(&myexit), "quit");