Parcourir la source

add `gc_mark`

blueloveTH il y a 9 mois
Parent
commit
67296767c7

+ 1 - 1
3rd/libhv/src/HttpServer.cpp

@@ -2,7 +2,7 @@
 #include "WebSocketChannel.h"
 #include "libhv_bindings.hpp"
 #include "http/server/WebSocketServer.h"
-#include "pocketpy/pocketpy.h"
+#include "pocketpy.h"
 
 struct libhv_HttpServer {
     hv::HttpService http_service;

+ 1 - 1
3rd/libhv/src/WebSocketClient.cpp

@@ -1,6 +1,6 @@
 #include "HttpMessage.h"
 #include "libhv_bindings.hpp"
-#include "pocketpy/pocketpy.h"
+#include "pocketpy.h"
 #include "http/client/WebSocketClient.h"
 
 struct libhv_WebSocketClient {

+ 4 - 0
include/pocketpy.h

@@ -1,3 +1,7 @@
 #pragma once
 
+#define PK_IS_PUBLIC_INCLUDE
+
 #include "pocketpy/pocketpy.h"
+
+#undef PK_IS_PUBLIC_INCLUDE

+ 8 - 0
include/pocketpy/pocketpy.h

@@ -28,6 +28,12 @@ typedef double py_f64;
 /// A generic destructor function.
 typedef void (*py_Dtor)(void*);
 
+#ifdef PK_IS_PUBLIC_INCLUDE
+    typedef struct py_TValue {
+        char _[16];
+    } py_TValue;
+#endif
+
 /// A string view type. It is helpful for passing strings which are not null-terminated.
 typedef struct c11_sv {
     const char* data;
@@ -72,6 +78,8 @@ typedef struct py_Callbacks {
     void (*flush)();
     /// Used by `input` to get a character.
     int (*getchar)();
+    /// Used by `gc.collect()` to mark extra objects for garbage collection.
+    void (*gc_mark)(void (*f)(py_Ref val, void* ctx), void* ctx);
 } py_Callbacks;
 
 /// Native function signature.

+ 7 - 0
src/interpreter/vm.c

@@ -635,6 +635,11 @@ void CodeObject__gc_mark(const CodeObject* self, c11_vector* p_stack) {
     }
 }
 
+static void pk__mark_value_func(py_Ref val, void* ctx) {
+    c11_vector* p_stack = ctx;
+    pk__mark_value(val);
+}
+
 void ManagedHeap__mark(ManagedHeap* self) {
     VM* vm = pk_current_vm;
     c11_vector* p_stack = &self->gc_roots;
@@ -666,6 +671,8 @@ void ManagedHeap__mark(ManagedHeap* self) {
     for(int i = 0; i < c11__count_array(vm->reg); i++) {
         pk__mark_value(&vm->reg[i]);
     }
+    // mark user func
+    if(vm->callbacks.gc_mark) vm->callbacks.gc_mark(pk__mark_value_func, p_stack);
     /*****************************/
     while(p_stack->length > 0) {
         PyObject* obj = c11_vector__back(PyObject*, p_stack);