blueloveTH 2 роки тому
батько
коміт
724f693761
5 змінених файлів з 77 додано та 48 видалено
  1. 52 21
      include/pocketpy/obj.h
  2. 6 8
      src/base64.cpp
  3. 3 3
      src/ceval.cpp
  4. 10 10
      src/io.cpp
  5. 6 6
      src/pocketpy.cpp

+ 52 - 21
include/pocketpy/obj.h

@@ -48,43 +48,74 @@ struct StarWrapper{
 };
 
 struct Bytes{
-    std::vector<char> _v;
-    bool valid;
+    unsigned char* _data;
+    int _size;
 
-    int size() const noexcept { return (int)_v.size(); }
-    int operator[](int i) const noexcept { return (int)(uint8_t)_v[i]; }
-    const char* data() const noexcept { return _v.data(); }
+    int size() const noexcept { return _size; }
+    int operator[](int i) const noexcept { return (int)_data[i]; }
+    const unsigned char* data() const noexcept { return _data; }
 
-    bool operator==(const Bytes& rhs) const{ return _v == rhs._v && valid == rhs.valid; }
-    bool operator!=(const Bytes& rhs) const{ return _v != rhs._v || valid != rhs.valid; }
+    bool operator==(const Bytes& rhs) const{
+        if(_size != rhs._size) return false;
+        for(int i=0; i<_size; i++) if(_data[i] != rhs._data[i]) return false;
+        return true;
+    }
+    bool operator!=(const Bytes& rhs) const{ return !(*this == rhs); }
 
-    Str str() const noexcept { return Str(_v.data(), _v.size()); }
-    std::string_view sv() const noexcept { return std::string_view(_v.data(), _v.size()); }
+    Str str() const noexcept { return Str((char*)_data, _size); }
+    std::string_view sv() const noexcept { return std::string_view((char*)_data, _size); }
 
-    Bytes() : valid(false) {}
-    Bytes(std::vector<char>&& v): _v(std::move(v)), valid(true) {}
-    Bytes(std::string_view sv): valid(true) {
-        _v.resize(sv.size());
-        for(int i=0; i<sv.size(); i++) _v[i] = sv[i];
+    Bytes() : _data(nullptr), _size(0) {}
+    Bytes(unsigned char* p, int size): _data(p), _size(size) {}
+    Bytes(const std::vector<unsigned char>& v){
+        _data = new unsigned char[v.size()];
+        _size = v.size();
+        for(int i=0; i<_size; i++) _data[i] = v[i];
+    }
+    Bytes(std::string_view sv){
+        _data = new unsigned char[sv.size()];
+        _size = sv.size();
+        for(int i=0; i<_size; i++) _data[i] = sv[i];
     }
     Bytes(const Str& str): Bytes(str.sv()) {}
-    operator bool() const noexcept { return valid; }
+    operator bool() const noexcept { return _data != nullptr; }
 
     // copy constructor
-    Bytes(const Bytes& rhs) : _v(rhs._v), valid(rhs.valid) {}
+    Bytes(const Bytes& rhs){
+        _data = new unsigned char[rhs._size];
+        _size = rhs._size;
+        for(int i=0; i<_size; i++) _data[i] = rhs._data[i];
+    }
 
     // move constructor
-    Bytes(Bytes&& rhs) noexcept : _v(std::move(rhs._v)), valid(rhs.valid) {
-        rhs.valid = false;
+    Bytes(Bytes&& rhs) noexcept {
+        _data = rhs._data;
+        _size = rhs._size;
+        rhs._data = nullptr;
+        rhs._size = 0;
     }
 
     Bytes& operator=(Bytes&& rhs) noexcept {
-        _v = std::move(rhs._v);
-        valid = rhs.valid;
-        rhs.valid = false;
+        delete[] _data;
+        _data = rhs._data;
+        _size = rhs._size;
+        rhs._data = nullptr;
+        rhs._size = 0;
         return *this;
     }
 
+    std::pair<unsigned char*, int> detach() noexcept {
+        unsigned char* p = _data;
+        int size = _size;
+        _data = nullptr;
+        _size = 0;
+        return {p, size};
+    }
+
+    ~Bytes(){
+        delete[] _data;
+    }
+
     // delete copy assignment
     Bytes& operator=(const Bytes& rhs) = delete;
 };

+ 6 - 8
src/base64.cpp

@@ -171,19 +171,17 @@ void add_module_base64(VM* vm){
     // b64encode
     vm->bind_func<1>(mod, "b64encode", [](VM* vm, ArgsView args){
         Bytes& b = CAST(Bytes&, args[0]);
-        std::vector<char> out(b.size() * 2);
-        int size = base64_encode((const unsigned char*)b.data(), b.size(), out.data());
-        out.resize(size);
-        return VAR(Bytes(std::move(out)));
+		unsigned char* p = new unsigned char[b.size() * 2];
+        int size = base64_encode((const unsigned char*)b.data(), b.size(), (char*)p);
+        return VAR(Bytes(p, size));
     });
 
     // b64decode
     vm->bind_func<1>(mod, "b64decode", [](VM* vm, ArgsView args){
         Bytes& b = CAST(Bytes&, args[0]);
-        std::vector<char> out(b.size());
-        int size = base64_decode(b.data(), b.size(), (unsigned char*)out.data());
-        out.resize(size);
-        return VAR(Bytes(std::move(out)));
+        unsigned char* p = new unsigned char[b.size()];
+        int size = base64_decode((const char*)b.data(), b.size(), p);
+        return VAR(Bytes(p, size));
     });
 }
 

+ 3 - 3
src/ceval.cpp

@@ -248,9 +248,9 @@ __NEXT_STEP:;
     } DISPATCH();
     TARGET(BUILD_BYTES) {
         const Str& s = CAST(Str&, TOP());
-        std::vector<char> buffer(s.size);
-        memcpy(buffer.data(), s.data, s.size);
-        TOP() = VAR(Bytes(std::move(buffer)));
+        unsigned char* p = new unsigned char[s.size];
+        memcpy(p, s.data, s.size);
+        TOP() = VAR(Bytes(p, s.size));
     } DISPATCH();
     TARGET(BUILD_TUPLE)
         _0 = VAR(STACK_VIEW(byte.arg).to_tuple());

+ 10 - 10
src/io.cpp

@@ -32,12 +32,13 @@ Bytes _default_import_handler(const Str& name){
     FILE* fp = io_fopen(cname.c_str(), "rb");
     if(!fp) return Bytes();
     fseek(fp, 0, SEEK_END);
-    std::vector<char> buffer(ftell(fp));
+    int buffer_size = ftell(fp);
+    unsigned char* buffer = new unsigned char[buffer_size];
     fseek(fp, 0, SEEK_SET);
-    size_t sz = io_fread(buffer.data(), 1, buffer.size(), fp);
+    size_t sz = io_fread(buffer, 1, buffer_size, fp);
     PK_UNUSED(sz);
     fclose(fp);
-    return Bytes(std::move(buffer));
+    return Bytes(buffer, buffer_size);
 #else
     return Bytes();
 #endif
@@ -55,14 +56,13 @@ Bytes _default_import_handler(const Str& name){
         vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){
             FileIO& io = CAST(FileIO&, args[0]);
             fseek(io.fp, 0, SEEK_END);
-            std::vector<char> buffer(ftell(io.fp));
+            int buffer_size = ftell(io.fp);
+            unsigned char* buffer = new unsigned char[buffer_size];
             fseek(io.fp, 0, SEEK_SET);
-            size_t sz = io_fread(buffer.data(), 1, buffer.size(), io.fp);
-            PK_ASSERT(sz <= buffer.size());
-            // in text mode, CR may be dropped, which may cause `sz < buffer.size()`
-            if(sz < buffer.size()) buffer.resize(sz);
-            PK_UNUSED(sz);
-            Bytes b(std::move(buffer));
+            size_t actual_size = io_fread(buffer, 1, buffer_size, io.fp);
+            PK_ASSERT(actual_size <= buffer_size);
+            // in text mode, CR may be dropped, which may cause `actual_size < buffer_size`
+            Bytes b(buffer, actual_size);
             if(io.is_text()) return VAR(b.str());
             return VAR(std::move(b));
         });

+ 6 - 6
src/pocketpy.cpp

@@ -653,9 +653,9 @@ void init_builtins(VM* _vm) {
 
     _vm->bind_method<0>("str", "encode", [](VM* vm, ArgsView args) {
         const Str& self = _CAST(Str&, args[0]);
-        std::vector<char> buffer(self.length());
-        memcpy(buffer.data(), self.data, self.length());
-        return VAR(Bytes(std::move(buffer)));
+        unsigned char* buffer = new unsigned char[self.length()];
+        memcpy(buffer, self.data, self.length());
+        return VAR(Bytes(buffer, self.length()));
     });
 
     _vm->bind_method<1>("str", "join", [](VM* vm, ArgsView args) {
@@ -1027,13 +1027,13 @@ void init_builtins(VM* _vm) {
     /************ bytes ************/
     _vm->bind_constructor<2>("bytes", [](VM* vm, ArgsView args){
         List& list = CAST(List&, args[1]);
-        std::vector<char> buffer(list.size());
+        std::vector<unsigned char> buffer(list.size());
         for(int i=0; i<list.size(); i++){
             i64 b = CAST(i64, list[i]);
             if(b<0 || b>255) vm->ValueError("byte must be in range[0, 256)");
             buffer[i] = (char)b;
         }
-        return VAR(Bytes(std::move(buffer)));
+        return VAR(Bytes(buffer));
     });
 
     _vm->bind__getitem__(_vm->tp_bytes, [](VM* vm, PyObject* obj, PyObject* index) {
@@ -1045,7 +1045,7 @@ void init_builtins(VM* _vm) {
 
     _vm->bind__hash__(_vm->tp_bytes, [](VM* vm, PyObject* obj) {
         const Bytes& self = _CAST(Bytes&, obj);
-        std::string_view view(self.data(), self.size());
+        std::string_view view((char*)self.data(), self.size());
         return (i64)std::hash<std::string_view>()(view);
     });