diff --git a/CMakeLists.txt b/CMakeLists.txt index 50fe4da4..cdffae6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,9 @@ if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR- /EHsc /utf-8 /O2") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fexceptions -O2") + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + endif() endif() option(PK_EXPORT_C_API "Export C API" ON) diff --git a/README.md b/README.md index d74ee0ee..0d786043 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ To compile it with your project, these flags must be set: + `--std=c++17` flag must be set + Exception must be enabled + RTTI is not required ++ If clang is used, `-stdlib=libc++` must be set !!! For maximum performance, we recommend to use `clang++` with `-O2` flag. diff --git a/docs/quick-start/installation.md b/docs/quick-start/installation.md index 3de66c02..44d3e0ce 100644 --- a/docs/quick-start/installation.md +++ b/docs/quick-start/installation.md @@ -23,6 +23,7 @@ To compile it with your project, these flags must be set: + `--std=c++17` flag must be set + Exception must be enabled + RTTI is not required ++ If clang is used, `-stdlib=libc++` must be set ### Example diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index 7a191011..0291faba 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -163,27 +163,18 @@ inline bool is_unicode_Lo_char(uint32_t c) { struct StrName { uint16_t index; - StrName(): index(0) {} - explicit StrName(uint16_t index): index(index) {} - StrName(const char* s): index(get(s).index) {} - StrName(const Str& s){ - index = get(s.sv()).index; - } - std::string_view sv() const { return _r_interned[index-1].sv(); } + StrName(); + explicit StrName(uint16_t index); + StrName(const char* s); + StrName(const Str& s); + std::string_view sv() const; bool empty() const { return index == 0; } friend std::ostream& operator<<(std::ostream& os, const StrName& sn){ return os << sn.sv(); } - static bool is_valid(int index) { - // check _r_interned[index-1] is valid - return index > 0 && index <= _r_interned.size(); - } - - Str escape() const { - return _r_interned[index-1].escape(); - } + Str escape() const; bool operator==(const StrName& other) const noexcept { return this->index == other.index; @@ -204,14 +195,8 @@ struct StrName { inline static std::map> _interned; inline static std::vector _r_interned; - static StrName get(std::string_view s){ - auto it = _interned.find(s); - if(it != _interned.end()) return StrName(it->second); - uint16_t index = (uint16_t)(_r_interned.size() + 1); - _interned[s] = index; - _r_interned.push_back(s); - return StrName(index); - } + static bool is_valid(int index); + static StrName get(std::string_view s); }; struct FastStrStream{ diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 5a46b0af..b9d368a9 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -145,10 +145,10 @@ void init_builtins(VM* _vm) { _vm->bind_builtin_func<1>("__import__", [](VM* vm, ArgsView args) { const Str& name = CAST(Str&, args[0]); - auto dot = name.sv().find_first_of("."); + auto dot = name.sv().find_last_of("."); if(dot != std::string_view::npos){ auto ext = name.sv().substr(dot); - if(ext == ".so" || ext == ".dll" || ext == ".dylib" || ext == ".pyd"){ + if(ext == ".so" || ext == ".dll" || ext == ".dylib"){ dylib_entry_t entry = load_dylib(name.c_str()); if(!entry){ vm->_error("ImportError", "cannot load dynamic library: " + name.escape()); diff --git a/src/str.cpp b/src/str.cpp index 35cb1f2b..68357643 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -239,4 +239,31 @@ namespace pkpy { int Str::u8_length() const { return _byte_index_to_unicode(size); } + + StrName StrName::get(std::string_view s){ + auto it = _interned.find(s); + if(it != _interned.end()) return StrName(it->second); + uint16_t index = (uint16_t)(_r_interned.size() + 1); + _interned[s] = index; + _r_interned.push_back(s); + return StrName(index); + } + + Str StrName::escape() const { + return _r_interned[index-1].escape(); + } + + bool StrName::is_valid(int index) { + // check _r_interned[index-1] is valid + return index > 0 && index <= _r_interned.size(); + } + + StrName::StrName(): index(0) {} + StrName::StrName(uint16_t index): index(index) {} + StrName::StrName(const char* s): index(get(s).index) {} + StrName::StrName(const Str& s){ + index = get(s.sv()).index; + } + + std::string_view StrName::sv() const { return _r_interned[index-1].sv(); } } // namespace pkpy \ No newline at end of file diff --git a/tests/dylib/build.sh b/tests/dylib/build.sh index 5fd6f97e..9a38f299 100644 --- a/tests/dylib/build.sh +++ b/tests/dylib/build.sh @@ -1,2 +1 @@ -SRC=$(find ../../src/ -name "*.cpp") clang++ -std=c++17 -fno-rtti -O2 -stdlib=libc++ -Wfatal-errors -o libtest.so test.cpp -I../../include -fPIC -shared \ No newline at end of file