blueloveTH 2 лет назад
Родитель
Сommit
16ef631bfd
5 измененных файлов с 28 добавлено и 16 удалено
  1. 1 1
      .github/workflows/main.yml
  2. 9 12
      src/obj.h
  3. 6 0
      src/pocketpy.h
  4. 1 3
      src/ref.h
  5. 11 0
      src/vm.h

+ 1 - 1
.github/workflows/main.yml

@@ -47,7 +47,7 @@ jobs:
         build_dir: web
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-      if: github.event_name == 'push'
+      if: github.event_name == 'push' && github.ref == 'refs/heads/main'
     - uses: actions/upload-artifact@v3
       with:
         path: output

+ 9 - 12
src/obj.h

@@ -87,6 +87,9 @@ public:
     virtual ~BaseIter() = default;
 };
 
+template <typename, typename=void> struct is_container_gc : std::false_type {};
+template <typename T> struct is_container_gc<T, std::void_t<decltype(T::_mark)>> : std::true_type {};
+
 struct GCHeader {
     bool enabled;   // whether this object is managed by GC
     bool marked;    // whether this object is marked
@@ -135,7 +138,7 @@ struct Py_ : PyObject {
 
     void mark() override {
         PyObject::mark();
-        // extra mark for `T`
+        if constexpr (is_container_gc<T>::value) _value._mark();
     }
 };
 
@@ -174,19 +177,13 @@ union BitsCvt {
     BitsCvt(f64 val) : _float(val) {}
 };
 
-template <typename, typename = void> struct is_py_class : std::false_type {};
+template <typename, typename=void> struct is_py_class : std::false_type {};
 template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {};
 
-template<typename T>
-void _check_py_class(VM* vm, PyObject* var);
-
-template<typename T>
-T py_pointer_cast(VM* vm, PyObject* var);
-
-template<typename T>
-T py_value_cast(VM* vm, PyObject* var);
-
-struct Discarded {};
+template<typename T> void _check_py_class(VM*, PyObject*);
+template<typename T> T py_pointer_cast(VM*, PyObject*);
+template<typename T> T py_value_cast(VM*, PyObject*);
+struct Discarded { };
 
 template<typename __T>
 __T py_cast(VM* vm, PyObject* obj) {

+ 6 - 0
src/pocketpy.h

@@ -755,6 +755,11 @@ inline void add_module_random(VM* vm){
     vm->_exec(code, mod);
 }
 
+inline void add_module_gc(VM* vm){
+    PyObject* mod = vm->new_module("gc");
+    vm->bind_func<0>(mod, "collect", CPP_LAMBDA(VAR(vm->gc_collect())));
+}
+
 inline void VM::post_init(){
     init_builtins(this);
     add_module_sys(this);
@@ -767,6 +772,7 @@ inline void VM::post_init(){
     add_module_io(this);
     add_module_os(this);
     add_module_c(this);
+    add_module_gc(this);
 
     for(const char* name: {"this", "functools", "collections", "heapq", "bisect"}){
         _lazy_modules[name] = kPythonLibs[name];

+ 1 - 3
src/ref.h

@@ -99,9 +99,7 @@ struct IndexRef : BaseRef {
     }
 
     void set(VM* vm, Frame* frame, PyObject* val) const{
-        Args args(3);
-        args[0] = obj; args[1] = index; args[2] = std::move(val);
-        vm->fast_call(__setitem__, std::move(args));
+        vm->fast_call(__setitem__, Args{obj, index, val});
     }
 
     void del(VM* vm, Frame* frame) const{

+ 11 - 0
src/vm.h

@@ -144,6 +144,11 @@ public:
         return nullptr;
     }
 
+    i64 gc_collect(){
+        heap.collect(this);
+        return 0;
+    }
+
     template<typename T>
     PyObject* gcnew(Type type, T&& val){
         PyObject* obj = new Py_<std::decay_t<T>>(type, std::forward<T>(val));
@@ -931,4 +936,10 @@ inline PyObject* VM::_exec(){
     }
 }
 
+inline std::vector<PyObject*> ManagedHeap::get_roots(VM *vm) {
+    std::vector<PyObject*> roots;
+    // ...
+    return roots;
+}
+
 }   // namespace pkpy