1
0
Эх сурвалжийг харах

fix https://github.com/pocketpy/pocketpy/issues/195

blueloveTH 2 жил өмнө
parent
commit
7a5ec84d14

+ 2 - 2
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."

+ 1 - 5
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);

+ 10 - 13
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<char *, int>);
     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 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 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 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);

+ 6 - 14
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<Str&>(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){

+ 42 - 45
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 PK_STR_ALLOCATE()                                   \
+        if(this->size < sizeof(this->_inlined)){            \
+            this->data = this->_inlined;                    \
+        }else{                                              \
+            this->data = (char*)pool64_alloc(this->size);   \
+        }
 
-#define STR_INIT()                                  \
-        _alloc();                                   \
-        for(int i=0; i<size; i++){                  \
-            data[i] = s[i];                         \
-            if(!isascii(s[i])) is_ascii = false;    \
+#define PK_STR_COPY_INIT(__s)  \
+        for(int i=0; i<this->size; 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<char *, int> detached) {
-        this->size = detached.second;
+    Str::Str(std::pair<char *, int> detached): size(detached.second), is_ascii(true) {
         this->data = detached.first;
-        this->is_ascii = true;
-        // check is_ascii
         for(int i=0; i<size; i++){
-            if(!isascii(data[i])){
-                is_ascii = false;
-                break;
-            }
+            if(!isascii(data[i])){ is_ascii = false; break; }
         }
     }
 
     Str::Str(const Str& other): size(other.size), is_ascii(other.is_ascii) {
-        _alloc();
+        PK_STR_ALLOCATE()
         memcpy(data, other.data, size);
+        data[size] = '\0';
     }
 
     Str::Str(Str&& other): size(other.size), is_ascii(other.is_ascii) {
@@ -66,7 +73,9 @@ int utf8len(unsigned char c, bool suppress){
             for(int i=0; i<size; i++) _inlined[i] = other._inlined[i];
         }else{
             data = other.data;
+            // zero out `other`
             other.data = other._inlined;
+            other.data[0] = '\0';
             other.size = 0;
         }
     }
@@ -84,20 +93,11 @@ int utf8len(unsigned char c, bool suppress){
         return other < str.sv();
     }
 
-    void Str::_alloc(){
-        if(size <= 16){
-            this->data = _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

+ 1 - 1
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);