mirror of
https://github.com/pocketpy/pocketpy
synced 2025-12-06 18:20:17 +00:00
small refactor
This commit is contained in:
parent
c45a5df1e8
commit
bfe471dc12
@ -3,18 +3,8 @@ icon: package
|
|||||||
label: gc
|
label: gc
|
||||||
---
|
---
|
||||||
|
|
||||||
### `gc.collect()`
|
Garbage collection interface module.
|
||||||
|
|
||||||
Invoke the garbage collector.
|
#### Source code
|
||||||
|
|
||||||
### `gc.enable()`
|
:::code source="../../include/typings/gc.pyi" :::
|
||||||
|
|
||||||
Enable automatic garbage collection.
|
|
||||||
|
|
||||||
### `gc.disable()`
|
|
||||||
|
|
||||||
Disable automatic garbage collection.
|
|
||||||
|
|
||||||
### `gc.isenabled()`
|
|
||||||
|
|
||||||
Return `True` if automatic garbage collection is enabled, `False` otherwise.
|
|
||||||
|
|||||||
@ -3,11 +3,9 @@ icon: package
|
|||||||
label: json
|
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`
|
:::code source="../../include/typings/json.pyi" :::
|
||||||
|
|
||||||
Encode a python object into a JSON string.
|
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ output: .retype
|
|||||||
url: https://pocketpy.dev
|
url: https://pocketpy.dev
|
||||||
branding:
|
branding:
|
||||||
title: pocketpy
|
title: pocketpy
|
||||||
label: v2.1.4
|
label: v2.1.5
|
||||||
logo: "./static/logo.png"
|
logo: "./static/logo.png"
|
||||||
favicon: "./static/logo.png"
|
favicon: "./static/logo.png"
|
||||||
meta:
|
meta:
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#define PK_VERSION "2.1.4"
|
#define PK_VERSION "2.1.5"
|
||||||
#define PK_VERSION_MAJOR 2
|
#define PK_VERSION_MAJOR 2
|
||||||
#define PK_VERSION_MINOR 1
|
#define PK_VERSION_MINOR 1
|
||||||
#define PK_VERSION_PATCH 4
|
#define PK_VERSION_PATCH 5
|
||||||
|
|
||||||
/*************** feature settings ***************/
|
/*************** feature settings ***************/
|
||||||
#ifndef PK_ENABLE_OS // can be overridden by cmake
|
#ifndef PK_ENABLE_OS // can be overridden by cmake
|
||||||
|
|||||||
@ -44,7 +44,7 @@ void ManagedHeap__dtor(ManagedHeap* self);
|
|||||||
ManagedHeapSwpetInfo* ManagedHeapSwpetInfo__new();
|
ManagedHeapSwpetInfo* ManagedHeapSwpetInfo__new();
|
||||||
void ManagedHeapSwpetInfo__delete(ManagedHeapSwpetInfo* self);
|
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__collect(ManagedHeap* self);
|
||||||
int ManagedHeap__sweep(ManagedHeap* self, ManagedHeapSwpetInfo* out_info);
|
int ManagedHeap__sweep(ManagedHeap* self, ManagedHeapSwpetInfo* out_info);
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#define kPoolArenaSize (120 * 1024)
|
#define kPoolArenaSize (120 * 1024)
|
||||||
#define kMultiPoolCount 5
|
#define kMultiPoolCount 5
|
||||||
#define kPoolMaxBlockSize (32 * kMultiPoolCount)
|
// #define kPoolMaxBlockSize (32 * kMultiPoolCount)
|
||||||
|
|
||||||
typedef struct PoolArena {
|
typedef struct PoolArena {
|
||||||
int block_size;
|
int block_size;
|
||||||
|
|||||||
27
include/typings/gc.pyi
Normal file
27
include/typings/gc.pyi
Normal 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."""
|
||||||
@ -1 +1,6 @@
|
|||||||
def isgeneratorfunction(obj) -> bool: ...
|
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
2
include/typings/json.pyi
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
def loads(s: str): ...
|
||||||
|
def dumps(obj, indent=0): ...
|
||||||
@ -1,4 +1,4 @@
|
|||||||
from typing import Self, Literal, Callable
|
from typing import Self, Literal
|
||||||
from vmath import vec2, vec2i
|
from vmath import vec2, vec2i
|
||||||
|
|
||||||
class TValue[T]:
|
class TValue[T]:
|
||||||
@ -16,11 +16,7 @@ configmacros: dict[str, int]
|
|||||||
|
|
||||||
def memory_usage() -> str:
|
def memory_usage() -> str:
|
||||||
"""Return a summary of the memory usage."""
|
"""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:
|
def currentvm() -> int:
|
||||||
"""Return the current VM index."""
|
"""Return the current VM index."""
|
||||||
|
|||||||
@ -729,7 +729,7 @@ __NEXT_STEP:
|
|||||||
}
|
}
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
case OP_CALL: {
|
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);
|
vectorcall_opcall(byte.arg & 0xFF, byte.arg >> 8);
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,8 +94,7 @@ static void ManagedHeap__fire_debug_callback(ManagedHeap* self, ManagedHeapSwpet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ManagedHeap__collect_if_needed(ManagedHeap* self) {
|
void ManagedHeap__collect_hint(ManagedHeap* self) {
|
||||||
if(!self->gc_enabled) return;
|
|
||||||
if(self->gc_counter < self->gc_threshold) return;
|
if(self->gc_counter < self->gc_threshold) return;
|
||||||
self->gc_counter = 0;
|
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) {
|
PyObject* ManagedHeap__gcnew(ManagedHeap* self, py_Type type, int slots, int udsize) {
|
||||||
assert(slots >= 0 || slots == -1);
|
assert(slots >= 0 || slots == -1);
|
||||||
PyObject* obj;
|
|
||||||
// header + slots + udsize
|
// header + slots + udsize
|
||||||
int size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + udsize;
|
int size = sizeof(PyObject) + PK_OBJ_SLOTS_SIZE(slots) + udsize;
|
||||||
if(size <= kPoolMaxBlockSize) {
|
PyObject* obj = MultiPool__alloc(&self->small_objects, size);
|
||||||
obj = MultiPool__alloc(&self->small_objects, size);
|
if(obj == NULL) {
|
||||||
assert(obj != NULL);
|
|
||||||
} else {
|
|
||||||
obj = PK_MALLOC(size);
|
obj = PK_MALLOC(size);
|
||||||
c11_vector__push(PyObject*, &self->large_objects, obj);
|
c11_vector__push(PyObject*, &self->large_objects, obj);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -141,7 +141,7 @@ static int Pool__sweep_dealloc(Pool* self,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* MultiPool__alloc(MultiPool* self, int size) {
|
void* MultiPool__alloc(MultiPool* self, int size) {
|
||||||
if(size == 0) return NULL;
|
assert(size > 0);
|
||||||
int index = (size - 1) >> 5;
|
int index = (size - 1) >> 5;
|
||||||
if(index < kMultiPoolCount) {
|
if(index < kMultiPoolCount) {
|
||||||
Pool* pool = &self->pools[index];
|
Pool* pool = &self->pools[index];
|
||||||
|
|||||||
@ -1,14 +1,6 @@
|
|||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
#include "pocketpy/interpreter/vm.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) {
|
static bool gc_enable(int argc, py_Ref argv) {
|
||||||
PY_CHECK_ARGC(0);
|
PY_CHECK_ARGC(0);
|
||||||
ManagedHeap* heap = &pk_current_vm->heap;
|
ManagedHeap* heap = &pk_current_vm->heap;
|
||||||
@ -32,11 +24,38 @@ static bool gc_isenabled(int argc, py_Ref argv) {
|
|||||||
return true;
|
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() {
|
void pk__add_module_gc() {
|
||||||
py_Ref mod = py_newmodule("gc");
|
py_Ref mod = py_newmodule("gc");
|
||||||
|
|
||||||
py_bindfunc(mod, "collect", gc_collect);
|
|
||||||
py_bindfunc(mod, "enable", gc_enable);
|
py_bindfunc(mod, "enable", gc_enable);
|
||||||
py_bindfunc(mod, "disable", gc_disable);
|
py_bindfunc(mod, "disable", gc_disable);
|
||||||
py_bindfunc(mod, "isenabled", gc_isenabled);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
#include "pocketpy/pocketpy.h"
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
#include "pocketpy/common/utils.h"
|
|
||||||
#include "pocketpy/objects/object.h"
|
#include "pocketpy/objects/object.h"
|
||||||
#include "pocketpy/common/sstream.h"
|
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
|
||||||
static bool inspect_isgeneratorfunction(int argc, py_Ref argv) {
|
static bool inspect_isgeneratorfunction(int argc, py_Ref argv) {
|
||||||
@ -21,8 +18,17 @@ static bool inspect_isgeneratorfunction(int argc, py_Ref argv) {
|
|||||||
return true;
|
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() {
|
void pk__add_module_inspect() {
|
||||||
py_Ref mod = py_newmodule("inspect");
|
py_Ref mod = py_newmodule("inspect");
|
||||||
|
|
||||||
py_bindfunc(mod, "isgeneratorfunction", inspect_isgeneratorfunction);
|
py_bindfunc(mod, "isgeneratorfunction", inspect_isgeneratorfunction);
|
||||||
}
|
py_bindfunc(mod, "is_user_defined_type", inspect_is_user_defined_type);
|
||||||
|
}
|
||||||
|
|||||||
@ -57,22 +57,6 @@ static bool pkpy_memory_usage(int argc, py_Ref argv) {
|
|||||||
return true;
|
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) {
|
static bool pkpy_currentvm(int argc, py_Ref argv) {
|
||||||
PY_CHECK_ARGC(0);
|
PY_CHECK_ARGC(0);
|
||||||
py_newint(py_retval(), py_currentvm());
|
py_newint(py_retval(), py_currentvm());
|
||||||
@ -538,8 +522,6 @@ void pk__add_module_pkpy() {
|
|||||||
py_pop();
|
py_pop();
|
||||||
|
|
||||||
py_bindfunc(mod, "memory_usage", pkpy_memory_usage);
|
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);
|
py_bindfunc(mod, "currentvm", pkpy_currentvm);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import gc
|
import gc
|
||||||
from pkpy import setup_gc_debug_callback
|
|
||||||
|
|
||||||
setup_gc_debug_callback(print)
|
gc.setup_debug_callback(print)
|
||||||
|
|
||||||
gc.collect()
|
gc.collect()
|
||||||
def create_garbage():
|
def create_garbage():
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from pkpy import is_user_defined_type
|
from inspect import is_user_defined_type
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
pass
|
pass
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user