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

some refactor

Update vm.cpp
blueloveTH пре 2 година
родитељ
комит
e00ddb8692
9 измењених фајлова са 32 додато и 47 уклоњено
  1. 0 2
      .gitignore
  2. 0 18
      docs/quick-start/modules.md
  3. 1 1
      include/pocketpy/io.h
  4. 6 1
      include/pocketpy/obj.h
  5. 1 1
      include/pocketpy/pocketpy_c.h
  6. 1 1
      include/pocketpy/vm.h
  7. 9 9
      src/io.cpp
  8. 1 6
      src/pocketpy_c.cpp
  9. 13 8
      src/vm.cpp

+ 0 - 2
.gitignore

@@ -36,7 +36,5 @@ main
 pypi/
 libpocketpy.dylib
 
-cmake-build-*
-
 .xmake/
 

+ 0 - 18
docs/quick-start/modules.md

@@ -60,24 +60,6 @@ When you do `import` a module, the VM will try to find it in the following order
 ### Customized import handler
 
 You can use `vm->_import_handler` to provide a custom import handler for the 3rd step.
-if both `enable_os` and `PK_ENABLE_OS` are `true`, the default `import_handler` is as follows:
-
-```cpp
-inline Bytes _default_import_handler(const Str& name){
-    std::filesystem::path path(name.sv());
-    bool exists = std::filesystem::exists(path);
-    if(!exists) return Bytes();
-    std::string cname = name.str();
-    FILE* fp = fopen(cname.c_str(), "rb");
-    if(!fp) return Bytes();
-    fseek(fp, 0, SEEK_END);
-    std::vector<char> buffer(ftell(fp));
-    fseek(fp, 0, SEEK_SET);
-    fread(buffer.data(), 1, buffer.size(), fp);
-    fclose(fp);
-    return Bytes(std::move(buffer));
-};
-```
 
 ### Import module via cpp
 

+ 1 - 1
include/pocketpy/io.h

@@ -3,7 +3,7 @@
 #include "cffi.h"
 
 namespace pkpy{
-    Bytes _default_import_handler(const Str& name);
+    unsigned char* _default_import_handler(const char*, int, int*);
     void add_module_os(VM* vm);
     void add_module_io(VM* vm);
 }

+ 6 - 1
include/pocketpy/obj.h

@@ -74,7 +74,12 @@ struct Bytes{
     Bytes& operator=(const Bytes& rhs) = delete;
     std::pair<unsigned char*, int> detach() noexcept;
 
-    ~Bytes(){ delete[] _data;}
+    ~Bytes(){
+        if(_data != nullptr){
+            free(_data);
+            _data = nullptr;
+        }
+    }
 };
 
 using Super = std::pair<PyObject*, Type>;

+ 1 - 1
include/pocketpy/pocketpy_c.h

@@ -13,7 +13,7 @@ extern "C" {
 typedef struct pkpy_vm_handle pkpy_vm;
 typedef int (*pkpy_CFunction)(pkpy_vm*);
 typedef void (*pkpy_COutputHandler)(pkpy_vm*, const char*, int);
-typedef const char* (*pkpy_CImportHandler)(const char*);
+typedef unsigned char* (*pkpy_CImportHandler)(const char*, int, int*);
 typedef int pkpy_CName;
 typedef int pkpy_CType;
 

+ 1 - 1
include/pocketpy/vm.h

@@ -142,7 +142,7 @@ public:
 
     PrintFunc _stdout;
     PrintFunc _stderr;
-    Bytes (*_import_handler)(const Str& name);
+    unsigned char* (*_import_handler)(const char*, int, int*);
 
     // for quick access
     Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;

+ 9 - 9
src/io.cpp

@@ -23,14 +23,13 @@ static size_t io_fread(void* buffer, size_t size, size_t count, FILE* fp){
 }
 
 
-Bytes _default_import_handler(const Str& name){
+unsigned char* _default_import_handler(const char* name_p, int name_size, int* out_size){
 #if PK_ENABLE_OS
-    std::filesystem::path path(name.sv());
-    bool exists = std::filesystem::exists(path);
-    if(!exists) return Bytes();
-    std::string cname = name.str();
-    FILE* fp = io_fopen(cname.c_str(), "rb");
-    if(!fp) return Bytes();
+    std::string name(name_p, name_size);
+    bool exists = std::filesystem::exists(std::filesystem::path(name));
+    if(!exists) return nullptr;
+    FILE* fp = io_fopen(name.c_str(), "rb");
+    if(!fp) return nullptr;
     fseek(fp, 0, SEEK_END);
     int buffer_size = ftell(fp);
     unsigned char* buffer = new unsigned char[buffer_size];
@@ -38,9 +37,10 @@ Bytes _default_import_handler(const Str& name){
     size_t sz = io_fread(buffer, 1, buffer_size, fp);
     PK_UNUSED(sz);
     fclose(fp);
-    return Bytes(buffer, buffer_size);
+    *out_size = buffer_size;
+    return buffer;
 #else
-    return Bytes();
+    return nullptr;
 #endif
 };
 

+ 1 - 6
src/pocketpy_c.cpp

@@ -586,12 +586,7 @@ void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler){
 
 void pkpy_set_import_handler(pkpy_vm* vm_handle, pkpy_CImportHandler handler){
     VM* vm = (VM*) vm_handle;
-    static pkpy_CImportHandler activeHandler;
-    activeHandler = handler;
-    vm->_import_handler = [](const Str& str) -> pkpy::Bytes {
-        const char* returnString = activeHandler(str.c_str());
-        return { Str(returnString) };
-    };
+    vm->_import_handler = handler;
 }
 
 void* pkpy_new_repl(pkpy_vm* vm_handle){

+ 13 - 8
src/vm.cpp

@@ -82,9 +82,11 @@ namespace pkpy{
         callstack.reserve(8);
         _main = nullptr;
         _last_exception = nullptr;
-        _import_handler = [](const Str& name) {
-            PK_UNUSED(name);
-            return Bytes();
+        _import_handler = [](const char* name_p, int name_size, int* out_size) -> unsigned char*{
+            PK_UNUSED(name_p);
+            PK_UNUSED(name_size);
+            PK_UNUSED(out_size);
+            return nullptr;
         };
         init_builtin_types();
     }
@@ -335,17 +337,20 @@ namespace pkpy{
         bool is_init = false;
         auto it = _lazy_modules.find(name);
         if(it == _lazy_modules.end()){
-            Bytes b = _import_handler(filename);
-            if(!b){
+            int out_size;
+            unsigned char* out = _import_handler(filename.data, filename.size, &out_size);
+            if(out == nullptr){
                 filename = path.replace('.', kPlatformSep).str() + kPlatformSep + "__init__.py";
                 is_init = true;
-                b = _import_handler(filename);
+                out = _import_handler(filename.data, filename.size, &out_size);
             }
-            if(!b){
+            if(out == nullptr){
                 if(throw_err) ImportError(fmt("module ", path.escape(), " not found"));
                 else return nullptr;
             }
-            source = Str(b.str());
+            PK_ASSERT(out_size >= 0)
+            source = Str(std::string_view((char*)out, out_size));
+            free(out);
         }else{
             source = it->second;
             _lazy_modules.erase(it);