small refactor

This commit is contained in:
blueloveTH 2025-11-24 11:41:37 +08:00
parent c45a5df1e8
commit bfe471dc12
18 changed files with 92 additions and 72 deletions

View File

@ -3,18 +3,8 @@ icon: package
label: gc
---
### `gc.collect()`
Garbage collection interface module.
Invoke the garbage collector.
#### Source code
### `gc.enable()`
Enable automatic garbage collection.
### `gc.disable()`
Disable automatic garbage collection.
### `gc.isenabled()`
Return `True` if automatic garbage collection is enabled, `False` otherwise.
:::code source="../../include/typings/gc.pyi" :::

View File

@ -3,11 +3,9 @@ icon: package
label: json
---
### `json.loads(data: str)`
JSON serialization and deserialization module.
Decode a JSON string into a python object.
#### Source code
### `json.dumps(obj, indent=0) -> str`
Encode a python object into a JSON string.
:::code source="../../include/typings/json.pyi" :::

View File

@ -3,7 +3,7 @@ output: .retype
url: https://pocketpy.dev
branding:
title: pocketpy
label: v2.1.4
label: v2.1.5
logo: "./static/logo.png"
favicon: "./static/logo.png"
meta:

View File

@ -1,10 +1,10 @@
#pragma once
// clang-format off
#define PK_VERSION "2.1.4"
#define PK_VERSION "2.1.5"
#define PK_VERSION_MAJOR 2
#define PK_VERSION_MINOR 1
#define PK_VERSION_PATCH 4
#define PK_VERSION_PATCH 5
/*************** feature settings ***************/
#ifndef PK_ENABLE_OS // can be overridden by cmake

View File

@ -44,7 +44,7 @@ void ManagedHeap__dtor(ManagedHeap* self);
ManagedHeapSwpetInfo* ManagedHeapSwpetInfo__new();
void ManagedHeapSwpetInfo__delete(ManagedHeapSwpetInfo* self);
void ManagedHeap__collect_if_needed(ManagedHeap* self);
void ManagedHeap__collect_hint(ManagedHeap* self);
int ManagedHeap__collect(ManagedHeap* self);
int ManagedHeap__sweep(ManagedHeap* self, ManagedHeapSwpetInfo* out_info);

View File

@ -5,7 +5,7 @@
#define kPoolArenaSize (120 * 1024)
#define kMultiPoolCount 5
#define kPoolMaxBlockSize (32 * kMultiPoolCount)
// #define kPoolMaxBlockSize (32 * kMultiPoolCount)
typedef struct PoolArena {
int block_size;

27
include/typings/gc.pyi Normal file
View File

@ -0,0 +1,27 @@
from typing import Callable
def isenabled() -> bool:
"""Check if automatic garbage collection is enabled."""
def enable() -> None:
"""Enable automatic garbage collection."""
def disable() -> None:
"""Disable automatic garbage collection."""
def collect() -> int:
"""Run a full collection immediately.
Returns an integer indicating the number of unreachable objects found.
"""
def collect_hint() -> None:
"""Hint the garbage collector to run a collection.
The typical usage scenario for this function is in frame-driven games,
where `gc.disable()` is called at the start of the game,
and `gc.collect_hint()` is called at the end of each frame.
"""
def setup_debug_callback(cb: Callable[[str], None] | None) -> None:
"""Setup a callback that will be triggered at the end of each collection."""

View File

@ -1 +1,6 @@
def isgeneratorfunction(obj) -> bool: ...
def is_user_defined_type(t: type) -> bool:
"""Check if a type is user-defined.
This means the type was created by executing python `class` statement."""

2
include/typings/json.pyi Normal file
View File

@ -0,0 +1,2 @@
def loads(s: str): ...
def dumps(obj, indent=0): ...

View File

@ -1,4 +1,4 @@
from typing import Self, Literal, Callable
from typing import Self, Literal
from vmath import vec2, vec2i
class TValue[T]:
@ -16,11 +16,7 @@ configmacros: dict[str, int]
def memory_usage() -> str:
"""Return a summary of the memory usage."""
def setup_gc_debug_callback(cb: Callable[[str], None]) -> None:
"""Setup a callback that will be triggered at the end of GC."""
def is_user_defined_type(t: type) -> bool:
"""Check if a type is user-defined. This means the type was created by executing python `class` statement."""
def currentvm() -> int:
"""Return the current VM index."""

View File

@ -729,7 +729,7 @@ __NEXT_STEP:
}
/*****************************************/
case OP_CALL: {
ManagedHeap__collect_if_needed(&self->heap);
if(self->heap.gc_enabled) ManagedHeap__collect_hint(&self->heap);
vectorcall_opcall(byte.arg & 0xFF, byte.arg >> 8);
DISPATCH();
}

View File

@ -94,8 +94,7 @@ static void ManagedHeap__fire_debug_callback(ManagedHeap* self, ManagedHeapSwpet
}
}
void ManagedHeap__collect_if_needed(ManagedHeap* self) {
if(!self->gc_enabled) return;
void ManagedHeap__collect_hint(ManagedHeap* self) {
if(self->gc_counter < self->gc_threshold) return;
self->gc_counter = 0;
@ -185,13 +184,10 @@ int ManagedHeap__sweep(ManagedHeap* self, ManagedHeapSwpetInfo* out_info) {
PyObject* ManagedHeap__gcnew(ManagedHeap* self, py_Type type, int slots, int udsize) {
assert(slots >= 0 || slots == -1);
PyObject* obj;
// header + slots + udsize
int size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + udsize;
if(size <= kPoolMaxBlockSize) {
obj = MultiPool__alloc(&self->small_objects, size);
assert(obj != NULL);
} else {
PyObject* obj = MultiPool__alloc(&self->small_objects, size);
if(obj == NULL) {
obj = PK_MALLOC(size);
c11_vector__push(PyObject*, &self->large_objects, obj);
}

View File

@ -141,7 +141,7 @@ static int Pool__sweep_dealloc(Pool* self,
}
void* MultiPool__alloc(MultiPool* self, int size) {
if(size == 0) return NULL;
assert(size > 0);
int index = (size - 1) >> 5;
if(index < kMultiPoolCount) {
Pool* pool = &self->pools[index];

View File

@ -1,14 +1,6 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/interpreter/vm.h"
static bool gc_collect(int argc, py_Ref argv) {
PY_CHECK_ARGC(0);
ManagedHeap* heap = &pk_current_vm->heap;
int res = ManagedHeap__collect(heap);
py_newint(py_retval(), res);
return true;
}
static bool gc_enable(int argc, py_Ref argv) {
PY_CHECK_ARGC(0);
ManagedHeap* heap = &pk_current_vm->heap;
@ -32,11 +24,38 @@ static bool gc_isenabled(int argc, py_Ref argv) {
return true;
}
static bool gc_collect(int argc, py_Ref argv) {
PY_CHECK_ARGC(0);
ManagedHeap* heap = &pk_current_vm->heap;
int res = ManagedHeap__collect(heap);
py_newint(py_retval(), res);
return true;
}
static bool gc_collect_hint(int argc, py_Ref argv) {
PY_CHECK_ARGC(0);
ManagedHeap* heap = &pk_current_vm->heap;
ManagedHeap__collect_hint(heap);
py_newnone(py_retval());
return true;
}
static bool gc_setup_debug_callback(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
ManagedHeap* heap = &pk_current_vm->heap;
heap->debug_callback = *argv;
py_newnone(py_retval());
return true;
}
void pk__add_module_gc() {
py_Ref mod = py_newmodule("gc");
py_bindfunc(mod, "collect", gc_collect);
py_bindfunc(mod, "enable", gc_enable);
py_bindfunc(mod, "disable", gc_disable);
py_bindfunc(mod, "isenabled", gc_isenabled);
py_bindfunc(mod, "collect", gc_collect);
py_bindfunc(mod, "collect_hint", gc_collect_hint);
py_bindfunc(mod, "setup_debug_callback", gc_setup_debug_callback);
}

View File

@ -1,8 +1,5 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/common/sstream.h"
#include "pocketpy/interpreter/vm.h"
static bool inspect_isgeneratorfunction(int argc, py_Ref argv) {
@ -21,8 +18,17 @@ static bool inspect_isgeneratorfunction(int argc, py_Ref argv) {
return true;
}
static bool inspect_is_user_defined_type(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
PY_CHECK_ARG_TYPE(0, tp_type);
py_TypeInfo* ti = py_touserdata(argv);
py_newbool(py_retval(), ti->is_python);
return true;
}
void pk__add_module_inspect() {
py_Ref mod = py_newmodule("inspect");
py_bindfunc(mod, "isgeneratorfunction", inspect_isgeneratorfunction);
py_bindfunc(mod, "is_user_defined_type", inspect_is_user_defined_type);
}

View File

@ -57,22 +57,6 @@ static bool pkpy_memory_usage(int argc, py_Ref argv) {
return true;
}
static bool pkpy_setup_gc_debug_callback(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
ManagedHeap* heap = &pk_current_vm->heap;
heap->debug_callback = *argv;
py_newnone(py_retval());
return true;
}
static bool pkpy_is_user_defined_type(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
PY_CHECK_ARG_TYPE(0, tp_type);
py_TypeInfo* ti = py_touserdata(argv);
py_newbool(py_retval(), ti->is_python);
return true;
}
static bool pkpy_currentvm(int argc, py_Ref argv) {
PY_CHECK_ARGC(0);
py_newint(py_retval(), py_currentvm());
@ -538,8 +522,6 @@ void pk__add_module_pkpy() {
py_pop();
py_bindfunc(mod, "memory_usage", pkpy_memory_usage);
py_bindfunc(mod, "setup_gc_debug_callback", pkpy_setup_gc_debug_callback);
py_bindfunc(mod, "is_user_defined_type", pkpy_is_user_defined_type);
py_bindfunc(mod, "currentvm", pkpy_currentvm);

View File

@ -1,7 +1,6 @@
import gc
from pkpy import setup_gc_debug_callback
setup_gc_debug_callback(print)
gc.setup_debug_callback(print)
gc.collect()
def create_garbage():

View File

@ -1,4 +1,4 @@
from pkpy import is_user_defined_type
from inspect import is_user_defined_type
class A:
pass