diff --git a/build.sh b/build.sh index fc6d3d72..c72d5a32 100644 --- a/build.sh +++ b/build.sh @@ -30,7 +30,7 @@ SRC=$(find src/ -name "*.cpp") echo "> Compiling and linking source files... " -FLAGS="-std=c++17 -s -O1 -stdlib=libc++ -Wfatal-errors -Iinclude" +FLAGS="-std=c++17 -O1 -stdlib=libc++ -Wfatal-errors -Iinclude" if [[ "$OSTYPE" == "darwin"* ]]; then LIB_EXTENSION=".dylib" @@ -46,7 +46,7 @@ clang++ $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared # compile main.cpp and link to libpocketpy.so echo "> Compiling main.cpp and linking to libpocketpy$LIB_EXTENSION..." -clang++ $FLAGS -o main -s -O1 src2/main.cpp -L. -lpocketpy $LINK_FLAGS +clang++ $FLAGS -o main -O1 src2/main.cpp -L. -lpocketpy $LINK_FLAGS if [ $? -eq 0 ]; then echo "Build completed. Type \"./main\" to enter REPL." diff --git a/include/pocketpy/pocketpy_c.h b/include/pocketpy/pocketpy_c.h index 27730e46..b58812c3 100644 --- a/include/pocketpy/pocketpy_c.h +++ b/include/pocketpy/pocketpy_c.h @@ -16,11 +16,7 @@ typedef void (*pkpy_COutputHandler)(const char*, int); typedef unsigned char* (*pkpy_CImportHandler)(const char*, int, int*); typedef int pkpy_CName; typedef int pkpy_CType; - -typedef struct{ - const char* data; - int size; -}pkpy_CString; +typedef const char* pkpy_CString; /* Basic Functions */ PK_EXPORT pkpy_vm* pkpy_new_vm(bool enable_os); diff --git a/include/pocketpy/str.h b/include/pocketpy/str.h index d4c082e3..78964332 100644 --- a/include/pocketpy/str.h +++ b/include/pocketpy/str.h @@ -13,25 +13,20 @@ struct Str{ int size; bool is_ascii; char* data; - char _inlined[16]; - - mutable const char* _cached_c_str = nullptr; + char _inlined[24]; bool is_inlined() const { return data == _inlined; } - Str(): size(0), is_ascii(true), data(_inlined) {} + Str(); Str(int size, bool is_ascii); Str(const std::string& s); Str(std::string_view s); - Str(std::nullptr_t) { PK_FATAL_ERROR(); } Str(const char* s); Str(const char* s, int len); Str(std::pair); Str(const Str& other); Str(Str&& other); - void _alloc(); - const char* begin() const { return data; } const char* end() const { return data + size; } char operator[](int idx) const { return data[idx]; } @@ -41,29 +36,30 @@ struct Str{ Str& operator=(const Str& other); Str operator+(const Str& other) const; + friend Str operator+(const char* p, const Str& str); Str operator+(const char* p) const; + bool operator==(const std::string_view other) const; + bool operator!=(const std::string_view other) const; + bool operator<(const std::string_view other) const; + friend bool operator<(const std::string_view other, const Str& str); + + bool operator==(const char* p) const; + bool operator!=(const char* p) const; + bool operator==(const Str& other) const; bool operator!=(const Str& other) const; - bool operator==(const std::string_view other) const; - bool operator!=(const std::string_view other) const; - bool operator==(const char* p) const; - bool operator!=(const char* p) const; bool operator<(const Str& other) const; bool operator>(const Str& other) const; bool operator<=(const Str& other) const; bool operator>=(const Str& other) const; - bool operator<(const std::string_view other) const; ~Str(); - friend Str operator+(const char* p, const Str& str); friend std::ostream& operator<<(std::ostream& os, const Str& str); - friend bool operator<(const std::string_view other, const Str& str); Str substr(int start, int len) const; Str substr(int start) const; - char* c_str_dup() const; const char* c_str() const; std::string_view sv() const; std::string str() const; @@ -95,6 +91,7 @@ struct StrName { StrName(const char* s); StrName(const Str& s); std::string_view sv() const; + const char* c_str() const; bool empty() const { return index == 0; } friend std::ostream& operator<<(std::ostream& os, const StrName& sn); diff --git a/src/pocketpy_c.cpp b/src/pocketpy_c.cpp index eecd21fb..eef94764 100644 --- a/src/pocketpy_c.cpp +++ b/src/pocketpy_c.cpp @@ -231,7 +231,7 @@ bool pkpy_to_bool(pkpy_vm* vm_handle, int i, bool* out){ bool pkpy_push_string(pkpy_vm* vm_handle, pkpy_CString value) { VM* vm = (VM*) vm_handle; PK_ASSERT_NO_ERROR() - PyObject* res = py_var(vm, std::string_view(value.data, value.size)); + PyObject* res = py_var(vm, value); vm->s_data.push(res); return true; } @@ -251,8 +251,7 @@ bool pkpy_to_string(pkpy_vm* vm_handle, int i, pkpy_CString* out){ PK_PROTECTED( PyObject* item = stack_item(vm, i); const Str& s = py_cast(vm, item); - out->data = s.data; - out->size = s.size; + *out = s.c_str(); ) return true; } @@ -503,7 +502,7 @@ bool pkpy_error(pkpy_vm* vm_handle, const char* name, pkpy_CString message) { std::cerr << "[warning] pkpy_error(): " << Str(name).escape() << " not found, fallback to 'Exception'" << std::endl; } } - vm->_c.error = vm->call(e_t, VAR(std::string_view(message.data, message.size))); + vm->_c.error = vm->call(e_t, VAR(message)); return false; } @@ -518,7 +517,7 @@ bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) { if (vm->_c.error == nullptr) return false; Exception& e = PK_OBJ_GET(Exception, vm->_c.error); if (message != nullptr) - *message = e.summary().c_str_dup(); + *message = strdup(e.summary().c_str()); else std::cout << e.summary() << std::endl; vm->_c.error = nullptr; @@ -548,10 +547,7 @@ void pkpy_free(void* p){ } pkpy_CString pkpy_string(const char* value){ - pkpy_CString s; - s.data = value; - s.size = strlen(value); - return s; + return value; } pkpy_CName pkpy_name(const char* name){ @@ -559,11 +555,7 @@ pkpy_CName pkpy_name(const char* name){ } pkpy_CString pkpy_name_to_string(pkpy_CName name){ - std::string_view sv = StrName(name).sv(); - pkpy_CString s; - s.data = sv.data(); - s.size = sv.size(); - return s; + return StrName(name).c_str(); } void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler){ diff --git a/src/str.cpp b/src/str.cpp index 3dd6c10c..aa4004b0 100644 --- a/src/str.cpp +++ b/src/str.cpp @@ -13,51 +13,58 @@ int utf8len(unsigned char c, bool suppress){ return 0; } - Str::Str(int size, bool is_ascii): size(size), is_ascii(is_ascii) { - _alloc(); - } - -#define STR_INIT() \ - _alloc(); \ - for(int i=0; isize < sizeof(this->_inlined)){ \ + this->data = this->_inlined; \ + }else{ \ + this->data = (char*)pool64_alloc(this->size); \ } +#define PK_STR_COPY_INIT(__s) \ + for(int i=0; isize; i++){ \ + this->data[i] = __s[i]; \ + if(!isascii(__s[i])) is_ascii = false; \ + } + + Str::Str(): size(0), is_ascii(true), data(_inlined) { + _inlined[0] = '\0'; + } + + Str::Str(int size, bool is_ascii): size(size), is_ascii(is_ascii) { + PK_STR_ALLOCATE() + } + Str::Str(const std::string& s): size(s.size()), is_ascii(true) { - STR_INIT() + PK_STR_ALLOCATE() + PK_STR_COPY_INIT(s) } Str::Str(std::string_view s): size(s.size()), is_ascii(true) { - STR_INIT() + PK_STR_ALLOCATE() + PK_STR_COPY_INIT(s) } Str::Str(const char* s): size(strlen(s)), is_ascii(true) { - STR_INIT() + PK_STR_ALLOCATE() + PK_STR_COPY_INIT(s) } Str::Str(const char* s, int len): size(len), is_ascii(true) { - STR_INIT() + PK_STR_ALLOCATE() + PK_STR_COPY_INIT(s) } -#undef STR_INIT - - Str::Str(std::pair detached) { - this->size = detached.second; + Str::Str(std::pair detached): size(detached.second), is_ascii(true) { this->data = detached.first; - this->is_ascii = true; - // check is_ascii for(int i=0; idata = _inlined; - }else{ - this->data = (char*)pool64_alloc(size); - } - } - Str& Str::operator=(const Str& other){ if(!is_inlined()) pool64_dealloc(data); size = other.size; is_ascii = other.is_ascii; - _cached_c_str = nullptr; - _alloc(); + PK_STR_ALLOCATE() memcpy(data, other.data, size); return *this; } @@ -164,7 +164,6 @@ int utf8len(unsigned char c, bool suppress){ Str::~Str(){ if(!is_inlined()) pool64_dealloc(data); - if(_cached_c_str != nullptr) free((void*)_cached_c_str); } Str Str::substr(int start, int len) const { @@ -177,18 +176,8 @@ int utf8len(unsigned char c, bool suppress){ return substr(start, size - start); } - char* Str::c_str_dup() const { - char* p = (char*)malloc(size + 1); - memcpy(p, data, size); - p[size] = 0; - return p; - } - const char* Str::c_str() const{ - if(_cached_c_str == nullptr){ - _cached_c_str = c_str_dup(); - } - return _cached_c_str; + return data; } std::string_view Str::sv() const { @@ -435,6 +424,11 @@ int utf8len(unsigned char c, bool suppress){ return std::string_view(str); } + const char* StrName::c_str() const{ + const std::string& str = _r_interned()[index]; + return str.c_str(); + } + Str SStream::str(){ // after this call, the buffer is no longer valid return Str(buffer.detach()); @@ -545,4 +539,7 @@ int utf8len(unsigned char c, bool suppress){ } } +#undef PK_STR_ALLOCATE +#undef PK_STR_COPY_INIT + } // namespace pkpy \ No newline at end of file diff --git a/src2/main.cpp b/src2/main.cpp index 171bfde3..4cbb7347 100644 --- a/src2/main.cpp +++ b/src2/main.cpp @@ -53,7 +53,7 @@ static int f_input(pkpy_vm* vm){ pkpy_CString prompt; bool ok = pkpy_to_string(vm, -1, &prompt); if(!ok) return 0; - std::cout << std::string_view(prompt.data, prompt.size) << std::flush; + std::cout << prompt << std::flush; } bool eof; std::string output = pkpy_platform_getline(&eof);