blueloveTH 2 лет назад
Родитель
Сommit
7669c67c38
6 измененных файлов с 110 добавлено и 99 удалено
  1. 1 2
      README_zh.md
  2. 1 1
      amalgamate.py
  3. 9 6
      docs/C-API/vm.md
  4. 2 2
      src/main.cpp
  5. 13 88
      src/pocketpy.h
  6. 84 0
      src/re.h

+ 1 - 2
README_zh.md

@@ -37,8 +37,7 @@ int main(){
     pkpy_vm_exec(vm, "print(sum(a))");
 
     // 释放资源
-    pkpy_delete(result);
-    pkpy_delete(vm);
+    pkpy_delete_vm(vm);
     return 0;
 }
 ```

+ 1 - 1
amalgamate.py

@@ -9,7 +9,7 @@ pipeline = [
 	["common.h", "memory.h", "vector.h", "str.h", "tuplelist.h", "namedict.h", "error.h", "lexer.h"],
 	["obj.h", "dict.h", "codeobject.h", "frame.h"],
 	["gc.h", "vm.h", "ceval.h", "expr.h", "compiler.h", "repl.h"],
-	["_generated.h", "cffi.h", "iter.h", "base64.h", "linalg.h", "easing.h", "requests.h", "io.h"],
+	["_generated.h", "cffi.h", "iter.h", "base64.h", "re.h", "linalg.h", "easing.h", "requests.h", "io.h"],
 	["export.h", "pocketpy.h"]
 ]
 

+ 9 - 6
docs/C-API/vm.md

@@ -20,11 +20,14 @@ Run a given source on a virtual machine.
 
 Advanced version of `pkpy_vm_exec`.
 
-#### `void pkpy_delete(void* p)`
+#### `void pkpy_free(void* p)`
 
-Delete a pointer allocated by `pkpy_xxx_xxx`.
-It can be `VM*`, `REPL*`, `char*`, etc.
+Free a pointer via `free`.
 
-!!!
-If the pointer is not allocated by `pkpy_xxx_xxx`, the behavior is undefined.
-!!!
+#### `void pkpy_delete_vm(VM* vm)`
+
+Delete a virtual machine.
+
+#### `void pkpy_delete_repl(REPL* repl)`
+
+Delete a REPL.

+ 2 - 2
src/main.cpp

@@ -22,7 +22,7 @@ int main(int argc, char** argv){
             if(eof) break;
             need_more_lines = pkpy_repl_input(repl, line.c_str());
         }
-        pkpy_delete(vm);
+        pkpy_delete_vm(vm);
         return 0;
     }
     
@@ -49,7 +49,7 @@ int main(int argc, char** argv){
 
         pkpy::PyObject* ret = nullptr;
         ret = vm->exec(src.c_str(), filepath.filename().string(), pkpy::EXEC_MODE);
-        pkpy_delete(vm);
+        pkpy_delete_vm(vm);
         return ret != nullptr ? 0 : 1;
     }
 

+ 13 - 88
src/pocketpy.h

@@ -14,6 +14,7 @@
 #include "_generated.h"
 #include "export.h"
 #include "vm.h"
+#include "re.h"
 
 namespace pkpy {
 
@@ -1263,83 +1264,6 @@ inline void add_module_dis(VM* vm){
     });
 }
 
-struct ReMatch {
-    PY_CLASS(ReMatch, re, Match)
-
-    i64 start;
-    i64 end;
-    std::cmatch m;
-    ReMatch(i64 start, i64 end, std::cmatch m) : start(start), end(end), m(m) {}
-
-    static void _register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind_notimplemented_constructor<ReMatch>(type);
-        vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start)));
-        vm->bind_method<0>(type, "end", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end)));
-
-        vm->bind_method<0>(type, "span", [](VM* vm, ArgsView args) {
-            auto& self = _CAST(ReMatch&, args[0]);
-            return VAR(Tuple({VAR(self.start), VAR(self.end)}));
-        });
-
-        vm->bind_method<1>(type, "group", [](VM* vm, ArgsView args) {
-            auto& self = _CAST(ReMatch&, args[0]);
-            int index = CAST(int, args[1]);
-            index = vm->normalized_index(index, self.m.size());
-            return VAR(self.m[index].str());
-        });
-    }
-};
-
-inline PyObject* _regex_search(const Str& pattern, const Str& string, bool from_start, VM* vm){
-    std::regex re(pattern.begin(), pattern.end());
-    std::cmatch m;
-    if(std::regex_search(string.begin(), string.end(), m, re)){
-        if(from_start && m.position() != 0) return vm->None;
-        i64 start = string._byte_index_to_unicode(m.position());
-        i64 end = string._byte_index_to_unicode(m.position() + m.length());
-        return VAR_T(ReMatch, start, end, m);
-    }
-    return vm->None;
-};
-
-inline void add_module_re(VM* vm){
-    PyObject* mod = vm->new_module("re");
-    ReMatch::register_class(vm, mod);
-
-    vm->bind_func<2>(mod, "match", [](VM* vm, ArgsView args) {
-        const Str& pattern = CAST(Str&, args[0]);
-        const Str& string = CAST(Str&, args[1]);
-        return _regex_search(pattern, string, true, vm);
-    });
-
-    vm->bind_func<2>(mod, "search", [](VM* vm, ArgsView args) {
-        const Str& pattern = CAST(Str&, args[0]);
-        const Str& string = CAST(Str&, args[1]);
-        return _regex_search(pattern, string, false, vm);
-    });
-
-    vm->bind_func<3>(mod, "sub", [](VM* vm, ArgsView args) {
-        const Str& pattern = CAST(Str&, args[0]);
-        const Str& repl = CAST(Str&, args[1]);
-        const Str& string = CAST(Str&, args[2]);
-        std::regex re(pattern.begin(), pattern.end());
-        return VAR(std::regex_replace(string.str(), re, repl.str()));
-    });
-
-    vm->bind_func<2>(mod, "split", [](VM* vm, ArgsView args) {
-        const Str& pattern = CAST(Str&, args[0]);
-        const Str& string = CAST(Str&, args[1]);
-        std::regex re(pattern.begin(), pattern.end());
-        std::cregex_token_iterator it(string.begin(), string.end(), re, -1);
-        std::cregex_token_iterator end;
-        List vec;
-        for(; it != end; ++it){
-            vec.push_back(VAR(it->str()));
-        }
-        return VAR(vec);
-    });
-}
-
 struct Random{
     PY_CLASS(Random, random, Random)
     std::mt19937 gen;
@@ -1469,17 +1393,10 @@ inline void VM::post_init(){
 }   // namespace pkpy
 
 /*************************GLOBAL NAMESPACE*************************/
-static std::map<void*, void(*)(void*)> _pk_deleter_map;
-
 extern "C" {
     PK_LEGACY_EXPORT
-    void pkpy_delete(void* p){
-        auto it = _pk_deleter_map.find(p);
-        if(it != _pk_deleter_map.end()){
-            it->second(p);
-        }else{
-            free(p);
-        }
+    void pkpy_free(void* p){
+        free(p);
     }
 
     PK_LEGACY_EXPORT
@@ -1501,7 +1418,6 @@ extern "C" {
     PK_LEGACY_EXPORT
     pkpy::REPL* pkpy_new_repl(pkpy::VM* vm){
         pkpy::REPL* p = new pkpy::REPL(vm);
-        _pk_deleter_map[p] = [](void* p){ delete (pkpy::REPL*)p; };
         return p;
     }
 
@@ -1518,10 +1434,19 @@ extern "C" {
     PK_LEGACY_EXPORT
     pkpy::VM* pkpy_new_vm(bool enable_os=true){
         pkpy::VM* p = new pkpy::VM(enable_os);
-        _pk_deleter_map[p] = [](void* p){ delete (pkpy::VM*)p; };
         return p;
     }
 
+    PK_LEGACY_EXPORT
+    void pkpy_delete_vm(pkpy::VM* vm){
+        delete vm;
+    }
+
+    PK_LEGACY_EXPORT
+    void pkpy_delete_repl(pkpy::REPL* repl){
+        delete repl;
+    }
+
     PK_LEGACY_EXPORT
     void pkpy_vm_gc_on_delete(pkpy::VM* vm, void (*f)(pkpy::VM *, pkpy::PyObject *)){
         vm->heap._gc_on_delete = f;

+ 84 - 0
src/re.h

@@ -0,0 +1,84 @@
+#pragma once
+
+#include "cffi.h"
+
+namespace pkpy{
+
+struct ReMatch {
+    PY_CLASS(ReMatch, re, Match)
+
+    i64 start;
+    i64 end;
+    std::cmatch m;
+    ReMatch(i64 start, i64 end, std::cmatch m) : start(start), end(end), m(m) {}
+
+    static void _register(VM* vm, PyObject* mod, PyObject* type){
+        vm->bind_notimplemented_constructor<ReMatch>(type);
+        vm->bind_method<0>(type, "start", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).start)));
+        vm->bind_method<0>(type, "end", CPP_LAMBDA(VAR(_CAST(ReMatch&, args[0]).end)));
+
+        vm->bind_method<0>(type, "span", [](VM* vm, ArgsView args) {
+            auto& self = _CAST(ReMatch&, args[0]);
+            return VAR(Tuple({VAR(self.start), VAR(self.end)}));
+        });
+
+        vm->bind_method<1>(type, "group", [](VM* vm, ArgsView args) {
+            auto& self = _CAST(ReMatch&, args[0]);
+            int index = CAST(int, args[1]);
+            index = vm->normalized_index(index, self.m.size());
+            return VAR(self.m[index].str());
+        });
+    }
+};
+
+inline PyObject* _regex_search(const Str& pattern, const Str& string, bool from_start, VM* vm){
+    std::regex re(pattern.begin(), pattern.end());
+    std::cmatch m;
+    if(std::regex_search(string.begin(), string.end(), m, re)){
+        if(from_start && m.position() != 0) return vm->None;
+        i64 start = string._byte_index_to_unicode(m.position());
+        i64 end = string._byte_index_to_unicode(m.position() + m.length());
+        return VAR_T(ReMatch, start, end, m);
+    }
+    return vm->None;
+};
+
+inline void add_module_re(VM* vm){
+    PyObject* mod = vm->new_module("re");
+    ReMatch::register_class(vm, mod);
+
+    vm->bind_func<2>(mod, "match", [](VM* vm, ArgsView args) {
+        const Str& pattern = CAST(Str&, args[0]);
+        const Str& string = CAST(Str&, args[1]);
+        return _regex_search(pattern, string, true, vm);
+    });
+
+    vm->bind_func<2>(mod, "search", [](VM* vm, ArgsView args) {
+        const Str& pattern = CAST(Str&, args[0]);
+        const Str& string = CAST(Str&, args[1]);
+        return _regex_search(pattern, string, false, vm);
+    });
+
+    vm->bind_func<3>(mod, "sub", [](VM* vm, ArgsView args) {
+        const Str& pattern = CAST(Str&, args[0]);
+        const Str& repl = CAST(Str&, args[1]);
+        const Str& string = CAST(Str&, args[2]);
+        std::regex re(pattern.begin(), pattern.end());
+        return VAR(std::regex_replace(string.str(), re, repl.str()));
+    });
+
+    vm->bind_func<2>(mod, "split", [](VM* vm, ArgsView args) {
+        const Str& pattern = CAST(Str&, args[0]);
+        const Str& string = CAST(Str&, args[1]);
+        std::regex re(pattern.begin(), pattern.end());
+        std::cregex_token_iterator it(string.begin(), string.end(), re, -1);
+        std::cregex_token_iterator end;
+        List vec;
+        for(; it != end; ++it){
+            vec.push_back(VAR(it->str()));
+        }
+        return VAR(vec);
+    });
+}
+
+}   // namespace pkpy