Преглед изворни кода

redesign `py_newstrn` and `py_newstrv`

blueloveTH пре 1 година
родитељ
комит
000fd1f087

+ 8 - 7
include/pocketpy/common/str.h

@@ -7,16 +7,16 @@
 #include <stdarg.h>
 #include <stdarg.h>
 
 
 /* string */
 /* string */
-typedef struct c11_string{
+typedef struct c11_string {
     // int size | char[] | '\0'
     // int size | char[] | '\0'
     int size;
     int size;
-    const char data[];      // flexible array member
+    char data[];  // flexible array member
 } c11_string;
 } c11_string;
 
 
 /* bytes */
 /* bytes */
-typedef struct c11_bytes{
+typedef struct c11_bytes {
     int size;
     int size;
-    unsigned char data[];   // flexible array member
+    unsigned char data[];  // flexible array member
 } c11_bytes;
 } c11_bytes;
 
 
 bool c11_bytes__eq(c11_bytes* self, c11_bytes* other);
 bool c11_bytes__eq(c11_bytes* self, c11_bytes* other);
@@ -33,6 +33,7 @@ c11_string* c11_string__new2(const char* data, int size);
 c11_string* c11_string__new3(const char* fmt, ...);
 c11_string* c11_string__new3(const char* fmt, ...);
 void c11_string__ctor(c11_string* self, const char* data);
 void c11_string__ctor(c11_string* self, const char* data);
 void c11_string__ctor2(c11_string* self, const char* data, int size);
 void c11_string__ctor2(c11_string* self, const char* data, int size);
+void c11_string__ctor3(c11_string* self, int size);
 c11_string* c11_string__copy(c11_string* self);
 c11_string* c11_string__copy(c11_string* self);
 void c11_string__delete(c11_string* self);
 void c11_string__delete(c11_string* self);
 c11_sv c11_string__sv(c11_string* self);
 c11_sv c11_string__sv(c11_string* self);
@@ -55,8 +56,8 @@ bool c11_sv__endswith(c11_sv self, c11_sv suffix);
 c11_string* c11_sv__replace(c11_sv self, char old, char new_);
 c11_string* c11_sv__replace(c11_sv self, char old, char new_);
 c11_string* c11_sv__replace2(c11_sv self, c11_sv old, c11_sv new_);
 c11_string* c11_sv__replace2(c11_sv self, c11_sv old, c11_sv new_);
 
 
-c11_vector/* T=c11_sv */ c11_sv__split(c11_sv self, char sep);
-c11_vector/* T=c11_sv */ c11_sv__split2(c11_sv self, c11_sv sep);
+c11_vector /* T=c11_sv */ c11_sv__split(c11_sv self, char sep);
+c11_vector /* T=c11_sv */ c11_sv__split2(c11_sv self, c11_sv sep);
 
 
 // misc
 // misc
 int c11__unicode_index_to_byte(const char* data, int i);
 int c11__unicode_index_to_byte(const char* data, int i);
@@ -65,7 +66,7 @@ int c11__byte_index_to_unicode(const char* data, int n);
 bool c11__is_unicode_Lo_char(int c);
 bool c11__is_unicode_Lo_char(int c);
 int c11__u8_header(unsigned char c, bool suppress);
 int c11__u8_header(unsigned char c, bool suppress);
 
 
-typedef enum IntParsingResult{
+typedef enum IntParsingResult {
     IntParsing_SUCCESS,
     IntParsing_SUCCESS,
     IntParsing_FAILURE,
     IntParsing_FAILURE,
     IntParsing_OVERFLOW,
     IntParsing_OVERFLOW,

+ 5 - 2
include/pocketpy/pocketpy.h

@@ -153,8 +153,10 @@ PK_EXPORT void py_newfloat(py_OutRef, py_f64);
 PK_EXPORT void py_newbool(py_OutRef, bool);
 PK_EXPORT void py_newbool(py_OutRef, bool);
 /// Create a `str` object from a null-terminated string (utf-8).
 /// Create a `str` object from a null-terminated string (utf-8).
 PK_EXPORT void py_newstr(py_OutRef, const char*);
 PK_EXPORT void py_newstr(py_OutRef, const char*);
-/// Create a `str` object from a char array (utf-8).
-PK_EXPORT void py_newstrn(py_OutRef, const char*, int);
+/// Create a `str` object with `n` UNINITIALIZED bytes plus `'\0'`.
+PK_EXPORT char* py_newstrn(py_OutRef, int);
+/// Create a `str` object from a `c11_sv`.
+PK_EXPORT void py_newstrv(py_OutRef, c11_sv);
 /// Create a `bytes` object with `n` UNINITIALIZED bytes.
 /// Create a `bytes` object with `n` UNINITIALIZED bytes.
 PK_EXPORT unsigned char* py_newbytes(py_OutRef, int n);
 PK_EXPORT unsigned char* py_newbytes(py_OutRef, int n);
 /// Create a `None` object.
 /// Create a `None` object.
@@ -504,6 +506,7 @@ PK_EXPORT void py_clearexc(py_StackRef p0);
 #define NameError(n) py_exception(tp_NameError, "name '%n' is not defined", (n))
 #define NameError(n) py_exception(tp_NameError, "name '%n' is not defined", (n))
 #define TypeError(...) py_exception(tp_TypeError, __VA_ARGS__)
 #define TypeError(...) py_exception(tp_TypeError, __VA_ARGS__)
 #define RuntimeError(...) py_exception(tp_RuntimeError, __VA_ARGS__)
 #define RuntimeError(...) py_exception(tp_RuntimeError, __VA_ARGS__)
+#define IOError(...) py_exception(tp_IOError, __VA_ARGS__)
 #define ValueError(...) py_exception(tp_ValueError, __VA_ARGS__)
 #define ValueError(...) py_exception(tp_ValueError, __VA_ARGS__)
 #define IndexError(...) py_exception(tp_IndexError, __VA_ARGS__)
 #define IndexError(...) py_exception(tp_IndexError, __VA_ARGS__)
 #define ImportError(...) py_exception(tp_ImportError, __VA_ARGS__)
 #define ImportError(...) py_exception(tp_ImportError, __VA_ARGS__)

+ 1 - 1
include/pybind11/internal/types.h

@@ -136,7 +136,7 @@ iterator interface<Dervied>::end() const {
 class str : public object {
 class str : public object {
     PKBIND_TYPE_IMPL(object, str, tp_str);
     PKBIND_TYPE_IMPL(object, str, tp_str);
 
 
-    str(const char* data, int size) : object(alloc_t{}) { py_newstrn(m_ptr, data, size); }
+    str(const char* data, int size) : object(alloc_t{}) { py_newstrv(m_ptr, (c11_sv){data, size}); }
 
 
     str(const char* data) : str(data, static_cast<int>(strlen(data))) {}
     str(const char* data) : str(data, static_cast<int>(strlen(data))) {}
 
 

+ 1 - 1
src/common/sstream.c

@@ -148,7 +148,7 @@ c11_string* c11_sbuf__submit(c11_sbuf* self) {
 
 
 void c11_sbuf__py_submit(c11_sbuf* self, py_Ref out) {
 void c11_sbuf__py_submit(c11_sbuf* self, py_Ref out) {
     c11_string* res = c11_sbuf__submit(self);
     c11_string* res = c11_sbuf__submit(self);
-    py_newstrn(out, res->data, res->size);
+    py_newstrv(out, (c11_sv){res->data, res->size});
     c11_string__delete(res);
     c11_string__delete(res);
 }
 }
 
 

+ 6 - 0
src/common/str.c

@@ -38,6 +38,12 @@ void c11_string__ctor2(c11_string* self, const char* data, int size) {
     p[size] = '\0';
     p[size] = '\0';
 }
 }
 
 
+void c11_string__ctor3(c11_string* self, int size) {
+    self->size = size;
+    char* p = (char*)self->data;
+    p[size] = '\0';
+}
+
 c11_string* c11_string__copy(c11_string* self) {
 c11_string* c11_string__copy(c11_string* self) {
     int total_size = sizeof(c11_string) + self->size + 1;
     int total_size = sizeof(c11_string) + self->size + 1;
     c11_string* retval = malloc(total_size);
     c11_string* retval = malloc(total_size);

+ 1 - 1
src/compiler/compiler.c

@@ -1209,7 +1209,7 @@ static int Ctx__add_const_string(Ctx* self, c11_sv key) {
         return *val;
         return *val;
     } else {
     } else {
         py_TValue tmp;
         py_TValue tmp;
-        py_newstrn(&tmp, key.data, key.size);
+        py_newstrv(&tmp, key);
         c11_vector__push(py_TValue, &self->co->consts, tmp);
         c11_vector__push(py_TValue, &self->co->consts, tmp);
         int index = self->co->consts.length - 1;
         int index = self->co->consts.length - 1;
         c11_smallmap_s2n__set(&self->co_consts_string_dedup_map,
         c11_smallmap_s2n__set(&self->co_consts_string_dedup_map,

+ 5 - 5
src/modules/linalg.c

@@ -163,7 +163,7 @@ static bool vec2__repr__(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     char buf[64];
     char buf[64];
     int size = snprintf(buf, 64, "vec2(%.4f, %.4f)", argv[0]._vec2.x, argv[0]._vec2.y);
     int size = snprintf(buf, 64, "vec2(%.4f, %.4f)", argv[0]._vec2.x, argv[0]._vec2.y);
-    py_newstrn(py_retval(), buf, size);
+    py_newstrv(py_retval(), (c11_sv){buf, size});
     return true;
     return true;
 }
 }
 
 
@@ -355,7 +355,7 @@ static bool mat3x3__repr__(int argc, py_Ref argv) {
                         m->data[6],
                         m->data[6],
                         m->data[7],
                         m->data[7],
                         m->data[8]);
                         m->data[8]);
-    py_newstrn(py_retval(), buf, size);
+    py_newstrv(py_retval(), (c11_sv){buf, size});
     return true;
     return true;
 }
 }
 
 
@@ -660,7 +660,7 @@ static bool vec2i__repr__(int argc, py_Ref argv) {
     c11_vec2i data = py_tovec2i(argv);
     c11_vec2i data = py_tovec2i(argv);
     char buf[64];
     char buf[64];
     int size = snprintf(buf, 64, "vec2i(%d, %d)", data.x, data.y);
     int size = snprintf(buf, 64, "vec2i(%d, %d)", data.x, data.y);
-    py_newstrn(py_retval(), buf, size);
+    py_newstrv(py_retval(), (c11_sv){buf, size});
     return true;
     return true;
 }
 }
 
 
@@ -693,7 +693,7 @@ static bool vec3i__repr__(int argc, py_Ref argv) {
     c11_vec3i data = py_tovec3i(argv);
     c11_vec3i data = py_tovec3i(argv);
     char buf[64];
     char buf[64];
     int size = snprintf(buf, 64, "vec3i(%d, %d, %d)", data.x, data.y, data.z);
     int size = snprintf(buf, 64, "vec3i(%d, %d, %d)", data.x, data.y, data.z);
-    py_newstrn(py_retval(), buf, size);
+    py_newstrv(py_retval(), (c11_sv){buf, size});
     return true;
     return true;
 }
 }
 
 
@@ -730,7 +730,7 @@ static bool vec3__repr__(int argc, py_Ref argv) {
     c11_vec3 data = py_tovec3(argv);
     c11_vec3 data = py_tovec3(argv);
     char buf[64];
     char buf[64];
     int size = snprintf(buf, 64, "vec3(%.4f, %.4f, %.4f)", data.x, data.y, data.z);
     int size = snprintf(buf, 64, "vec3(%.4f, %.4f, %.4f)", data.x, data.y, data.z);
-    py_newstrn(py_retval(), buf, size);
+    py_newstrv(py_retval(), (c11_sv){buf, size});
     return true;
     return true;
 }
 }
 
 

+ 3 - 2
src/public/modules.c

@@ -43,7 +43,7 @@ py_Ref py_newmodule(const char* path) {
         const char* start = path + last_dot + 1;
         const char* start = path + last_dot + 1;
         py_newstr(r1, start);
         py_newstr(r1, start);
         py_setdict(r0, __name__, r1);
         py_setdict(r0, __name__, r1);
-        py_newstrn(r1, path, last_dot);
+        py_newstrv(r1, (c11_sv){path, last_dot});
         py_setdict(r0, __package__, r1);
         py_setdict(r0, __package__, r1);
     }
     }
 
 
@@ -404,7 +404,8 @@ static bool builtins_chr(int argc, py_Ref argv) {
     PY_CHECK_ARG_TYPE(0, tp_int);
     PY_CHECK_ARG_TYPE(0, tp_int);
     py_i64 val = py_toint(py_arg(0));
     py_i64 val = py_toint(py_arg(0));
     if(val < 0 || val > 128) { return ValueError("chr() arg not in range(128)"); }
     if(val < 0 || val > 128) { return ValueError("chr() arg not in range(128)"); }
-    py_newstrn(py_retval(), (const char*)&val, 1);
+    char* data = py_newstrn(py_retval(), 1);
+    data[0] = (char)val;
     return true;
     return true;
 }
 }
 
 

+ 1 - 1
src/public/py_number.c

@@ -210,7 +210,7 @@ static bool int__repr__(int argc, py_Ref argv) {
     py_i64 val = py_toint(&argv[0]);
     py_i64 val = py_toint(&argv[0]);
     char buf[32];
     char buf[32];
     int size = snprintf(buf, sizeof(buf), "%lld", (long long)val);
     int size = snprintf(buf, sizeof(buf), "%lld", (long long)val);
-    py_newstrn(py_retval(), buf, size);
+    py_newstrv(py_retval(), (c11_sv){buf, size});
     return true;
     return true;
 }
 }
 
 

+ 20 - 14
src/public/py_str.c

@@ -6,17 +6,23 @@
 #include "pocketpy/interpreter/vm.h"
 #include "pocketpy/interpreter/vm.h"
 #include "pocketpy/common/sstream.h"
 #include "pocketpy/common/sstream.h"
 
 
-void py_newstr(py_Ref out, const char* data) { py_newstrn(out, data, strlen(data)); }
+void py_newstr(py_Ref out, const char* data) { py_newstrv(out, (c11_sv){data, strlen(data)}); }
 
 
-void py_newstrn(py_Ref out, const char* data, int size) {
+char* py_newstrn(py_Ref out, int size) {
     ManagedHeap* heap = &pk_current_vm->heap;
     ManagedHeap* heap = &pk_current_vm->heap;
     int total_size = sizeof(c11_string) + size + 1;
     int total_size = sizeof(c11_string) + size + 1;
     PyObject* obj = ManagedHeap__gcnew(heap, tp_str, 0, total_size);
     PyObject* obj = ManagedHeap__gcnew(heap, tp_str, 0, total_size);
     c11_string* ud = PyObject__userdata(obj);
     c11_string* ud = PyObject__userdata(obj);
-    c11_string__ctor2(ud, data, size);
+    c11_string__ctor3(ud, size);
     out->type = tp_str;
     out->type = tp_str;
     out->is_ptr = true;
     out->is_ptr = true;
     out->_obj = obj;
     out->_obj = obj;
+    return ud->data;
+}
+
+void py_newstrv(py_OutRef out, c11_sv sv) {
+    char* data = py_newstrn(out, sv.size);
+    memcpy(data, sv.data, sv.size);
 }
 }
 
 
 unsigned char* py_newbytes(py_Ref out, int size) {
 unsigned char* py_newbytes(py_Ref out, int size) {
@@ -97,7 +103,7 @@ static bool str__add__(int argc, py_Ref argv) {
         int total_size = sizeof(c11_string) + self->size + other->size + 1;
         int total_size = sizeof(c11_string) + self->size + other->size + 1;
         c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
         c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
         res->size = self->size + other->size;
         res->size = self->size + other->size;
-        char* p = (char*)res->data;
+        char* p = res->data;
         memcpy(p, self->data, self->size);
         memcpy(p, self->data, self->size);
         memcpy(p + self->size, other->data, other->size);
         memcpy(p + self->size, other->data, other->size);
         p[res->size] = '\0';
         p[res->size] = '\0';
@@ -118,7 +124,7 @@ static bool str__mul__(int argc, py_Ref argv) {
             int total_size = sizeof(c11_string) + self->size * n + 1;
             int total_size = sizeof(c11_string) + self->size * n + 1;
             c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
             c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
             res->size = self->size * n;
             res->size = self->size * n;
-            char* p = (char*)res->data;
+            char* p = res->data;
             for(int i = 0; i < n; i++) {
             for(int i = 0; i < n; i++) {
                 memcpy(p + i * self->size, self->data, self->size);
                 memcpy(p + i * self->size, self->data, self->size);
             }
             }
@@ -174,14 +180,14 @@ static bool str__getitem__(int argc, py_Ref argv) {
         int index = py_toint(py_arg(1));
         int index = py_toint(py_arg(1));
         if(!pk__normalize_index(&index, self.size)) return false;
         if(!pk__normalize_index(&index, self.size)) return false;
         c11_sv res = c11_sv__u8_getitem(self, index);
         c11_sv res = c11_sv__u8_getitem(self, index);
-        py_newstrn(py_retval(), res.data, res.size);
+        py_newstrv(py_retval(), res);
         return true;
         return true;
     } else if(_1->type == tp_slice) {
     } else if(_1->type == tp_slice) {
         int start, stop, step;
         int start, stop, step;
         bool ok = pk__parse_int_slice(_1, c11_sv__u8_length(self), &start, &stop, &step);
         bool ok = pk__parse_int_slice(_1, c11_sv__u8_length(self), &start, &stop, &step);
         if(!ok) return false;
         if(!ok) return false;
         c11_string* res = c11_sv__u8_slice(self, start, stop, step);
         c11_string* res = c11_sv__u8_slice(self, start, stop, step);
-        py_newstrn(py_retval(), res->data, res->size);
+        py_newstrv(py_retval(), (c11_sv){res->data, res->size});
         c11_string__delete(res);
         c11_string__delete(res);
         return true;
         return true;
     } else {
     } else {
@@ -218,7 +224,7 @@ static bool str_lower(int argc, py_Ref argv) {
     int total_size = sizeof(c11_string) + self->size + 1;
     int total_size = sizeof(c11_string) + self->size + 1;
     c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
     c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
     res->size = self->size;
     res->size = self->size;
-    char* p = (char*)res->data;
+    char* p = res->data;
     for(int i = 0; i < self->size; i++) {
     for(int i = 0; i < self->size; i++) {
         char c = self->data[i];
         char c = self->data[i];
         p[i] = c >= 'A' && c <= 'Z' ? c + 32 : c;
         p[i] = c >= 'A' && c <= 'Z' ? c + 32 : c;
@@ -233,7 +239,7 @@ static bool str_upper(int argc, py_Ref argv) {
     int total_size = sizeof(c11_string) + self->size + 1;
     int total_size = sizeof(c11_string) + self->size + 1;
     c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
     c11_string* res = py_newobject(py_retval(), tp_str, 0, total_size);
     res->size = self->size;
     res->size = self->size;
-    char* p = (char*)res->data;
+    char* p = res->data;
     for(int i = 0; i < self->size; i++) {
     for(int i = 0; i < self->size; i++) {
         char c = self->data[i];
         char c = self->data[i];
         p[i] = c >= 'a' && c <= 'z' ? c - 32 : c;
         p[i] = c >= 'a' && c <= 'z' ? c - 32 : c;
@@ -303,7 +309,7 @@ static bool str_replace(int argc, py_Ref argv) {
     c11_string* new_ = py_touserdata(&argv[2]);
     c11_string* new_ = py_touserdata(&argv[2]);
     c11_string* res =
     c11_string* res =
         c11_sv__replace2(c11_string__sv(self), c11_string__sv(old), c11_string__sv(new_));
         c11_sv__replace2(c11_string__sv(self), c11_string__sv(old), c11_string__sv(new_));
-    py_newstrn(py_retval(), res->data, res->size);
+    py_newstrv(py_retval(), (c11_sv){res->data, res->size});
     c11_string__delete(res);
     c11_string__delete(res);
     return true;
     return true;
 }
 }
@@ -325,7 +331,7 @@ static bool str_split(int argc, py_Ref argv) {
     py_newlistn(py_retval(), res.length);
     py_newlistn(py_retval(), res.length);
     for(int i = 0; i < res.length; i++) {
     for(int i = 0; i < res.length; i++) {
         c11_sv item = c11__getitem(c11_sv, &res, i);
         c11_sv item = c11__getitem(c11_sv, &res, i);
-        py_newstrn(py_list_getitem(py_retval(), i), item.data, item.size);
+        py_newstrv(py_list_getitem(py_retval(), i), item);
     }
     }
     c11_vector__dtor(&res);
     c11_vector__dtor(&res);
     return true;
     return true;
@@ -353,7 +359,7 @@ static bool str__strip_impl(bool left, bool right, int argc, py_Ref argv) {
         return TypeError("strip() takes at most 2 arguments");
         return TypeError("strip() takes at most 2 arguments");
     }
     }
     c11_sv res = c11_sv__strip(self, chars, left, right);
     c11_sv res = c11_sv__strip(self, chars, left, right);
-    py_newstrn(py_retval(), res.data, res.size);
+    py_newstrv(py_retval(), res);
     return true;
     return true;
 }
 }
 
 
@@ -506,7 +512,7 @@ static bool str_iterator__next__(int argc, py_Ref argv) {
     int start = *ud;
     int start = *ud;
     int len = c11__u8_header(data[*ud], false);
     int len = c11__u8_header(data[*ud], false);
     *ud += len;
     *ud += len;
-    py_newstrn(py_retval(), data + start, len);
+    py_newstrv(py_retval(), (c11_sv){data + start, len});
     return true;
     return true;
 }
 }
 
 
@@ -629,7 +635,7 @@ static bool bytes_decode(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     int size;
     int size;
     unsigned char* data = py_tobytes(&argv[0], &size);
     unsigned char* data = py_tobytes(&argv[0], &size);
-    py_newstrn(py_retval(), (const char*)data, size);
+    py_newstrv(py_retval(), (c11_sv){(const char*)data, size});
     return true;
     return true;
 }
 }