mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 04:50:17 +00:00
fix a bug
This commit is contained in:
parent
352688e9ae
commit
6b9b5945a3
@ -68,14 +68,10 @@ struct CodeObject {
|
|||||||
|
|
||||||
void optimize(VM* vm);
|
void optimize(VM* vm);
|
||||||
|
|
||||||
void _mark() const {
|
void _gc_mark() const {
|
||||||
for(PyObject* v : consts) OBJ_MARK(v);
|
for(PyObject* v : consts) OBJ_MARK(v);
|
||||||
for(auto& decl: func_decls){
|
for(auto& decl: func_decls) decl->_gc_mark();
|
||||||
decl->kwargs._mark();
|
|
||||||
decl->code->_mark();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -33,11 +33,11 @@
|
|||||||
// debug macros
|
// debug macros
|
||||||
#define DEBUG_NO_BUILTIN_MODULES 0
|
#define DEBUG_NO_BUILTIN_MODULES 0
|
||||||
#define DEBUG_EXTRA_CHECK 0
|
#define DEBUG_EXTRA_CHECK 0
|
||||||
#define DEBUG_DIS_EXEC_REPL 0
|
#define DEBUG_DIS_EXEC 0
|
||||||
#define DEBUG_DIS_EXEC_REPL_MIN 1
|
#define DEBUG_DIS_EXEC_MIN 1
|
||||||
#define DEBUG_CEVAL_STEP 0
|
#define DEBUG_CEVAL_STEP 0
|
||||||
#define DEBUG_FULL_EXCEPTION 0
|
#define DEBUG_FULL_EXCEPTION 0
|
||||||
#define DEBUG_NO_GC 1
|
#define DEBUG_NO_GC 0
|
||||||
|
|
||||||
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
|
#if (defined(__ANDROID__) && __ANDROID_API__ <= 22) || defined(__EMSCRIPTEN__)
|
||||||
#define PK_ENABLE_FILEIO 0
|
#define PK_ENABLE_FILEIO 0
|
||||||
|
@ -154,15 +154,15 @@ struct Frame {
|
|||||||
_data.pop_back_n(n);
|
_data.pop_back_n(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mark() const {
|
void _gc_mark() const {
|
||||||
for(PyObject* obj : _data) OBJ_MARK(obj);
|
for(PyObject* obj : _data) OBJ_MARK(obj);
|
||||||
OBJ_MARK(_module);
|
OBJ_MARK(_module);
|
||||||
_locals->_mark();
|
if(_locals != nullptr) _locals->_gc_mark();
|
||||||
_closure->_mark();
|
if(_closure != nullptr) _closure->_gc_mark();
|
||||||
for(auto& p : s_try_block){
|
for(auto& p : s_try_block){
|
||||||
for(PyObject* obj : p.second) OBJ_MARK(obj);
|
for(PyObject* obj : p.second) OBJ_MARK(obj);
|
||||||
}
|
}
|
||||||
co->_mark();
|
co->_gc_mark();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
22
src/gc.h
22
src/gc.h
@ -133,36 +133,42 @@ struct ManagedHeap{
|
|||||||
void mark(VM* vm);
|
void mark(VM* vm);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void NameDict::_mark() const{
|
inline void NameDict::_gc_mark() const{
|
||||||
for(uint16_t i=0; i<_capacity; i++){
|
for(uint16_t i=0; i<_capacity; i++){
|
||||||
if(_items[i].first.empty()) continue;
|
if(_items[i].first.empty()) continue;
|
||||||
OBJ_MARK(_items[i].second);
|
OBJ_MARK(_items[i].second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline void _mark<List>(List& t){
|
inline void FuncDecl::_gc_mark() const{
|
||||||
|
code->_gc_mark();
|
||||||
|
kwargs._gc_mark();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> inline void _gc_mark<List>(List& t){
|
||||||
for(PyObject* obj: t) OBJ_MARK(obj);
|
for(PyObject* obj: t) OBJ_MARK(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline void _mark<Tuple>(Tuple& t){
|
template<> inline void _gc_mark<Tuple>(Tuple& t){
|
||||||
for(int i=0; i<t.size(); i++) OBJ_MARK(t[i]);
|
for(int i=0; i<t.size(); i++) OBJ_MARK(t[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline void _mark<Function>(Function& t){
|
template<> inline void _gc_mark<Function>(Function& t){
|
||||||
|
t.decl->_gc_mark();
|
||||||
if(t._module != nullptr) OBJ_MARK(t._module);
|
if(t._module != nullptr) OBJ_MARK(t._module);
|
||||||
if(t._closure != nullptr) t._closure->_mark();
|
if(t._closure != nullptr) t._closure->_gc_mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline void _mark<BoundMethod>(BoundMethod& t){
|
template<> inline void _gc_mark<BoundMethod>(BoundMethod& t){
|
||||||
OBJ_MARK(t.obj);
|
OBJ_MARK(t.obj);
|
||||||
OBJ_MARK(t.method);
|
OBJ_MARK(t.method);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline void _mark<StarWrapper>(StarWrapper& t){
|
template<> inline void _gc_mark<StarWrapper>(StarWrapper& t){
|
||||||
OBJ_MARK(t.obj);
|
OBJ_MARK(t.obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline void _mark<Super>(Super& t){
|
template<> inline void _gc_mark<Super>(Super& t){
|
||||||
OBJ_MARK(t.first);
|
OBJ_MARK(t.first);
|
||||||
}
|
}
|
||||||
// NOTE: std::function may capture some PyObject*, they can not be marked
|
// NOTE: std::function may capture some PyObject*, they can not be marked
|
||||||
|
12
src/iter.h
12
src/iter.h
@ -37,7 +37,7 @@ public:
|
|||||||
return p->operator[](index++);
|
return p->operator[](index++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mark() override {
|
void _gc_mark() const override {
|
||||||
OBJ_MARK(ref);
|
OBJ_MARK(ref);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -54,7 +54,7 @@ public:
|
|||||||
return VAR(str->u8_getitem(index++));
|
return VAR(str->u8_getitem(index++));
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mark() override {
|
void _gc_mark() const override {
|
||||||
OBJ_MARK(ref);
|
OBJ_MARK(ref);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -74,14 +74,14 @@ inline PyObject* Generator::next(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Generator::_mark(){
|
inline void Generator::_gc_mark() const{
|
||||||
if(frame!=nullptr) frame->_mark();
|
if(frame != nullptr) frame->_gc_mark();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void _mark(T& t){
|
void _gc_mark(T& t) {
|
||||||
if constexpr(std::is_base_of_v<BaseIter, T>){
|
if constexpr(std::is_base_of_v<BaseIter, T>){
|
||||||
t._mark();
|
t._gc_mark();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ while(!_items[i].first.empty()) { \
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mark() const;
|
void _gc_mark() const;
|
||||||
#undef HASH_PROBE
|
#undef HASH_PROBE
|
||||||
#undef _hash
|
#undef _hash
|
||||||
};
|
};
|
||||||
|
16
src/obj.h
16
src/obj.h
@ -38,6 +38,8 @@ struct FuncDecl {
|
|||||||
bool _2 = kwargs.contains(val);
|
bool _2 = kwargs.contains(val);
|
||||||
return _0 || _1 || _2;
|
return _0 || _1 || _2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _gc_mark() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
using FuncDecl_ = shared_ptr<FuncDecl>;
|
using FuncDecl_ = shared_ptr<FuncDecl>;
|
||||||
@ -87,7 +89,7 @@ protected:
|
|||||||
VM* vm;
|
VM* vm;
|
||||||
public:
|
public:
|
||||||
BaseIter(VM* vm) : vm(vm) {}
|
BaseIter(VM* vm) : vm(vm) {}
|
||||||
virtual void _mark() {}
|
virtual void _gc_mark() const {}
|
||||||
virtual PyObject* next() = 0;
|
virtual PyObject* next() = 0;
|
||||||
virtual ~BaseIter() = default;
|
virtual ~BaseIter() = default;
|
||||||
};
|
};
|
||||||
@ -107,14 +109,14 @@ struct PyObject {
|
|||||||
NameDict& attr() noexcept { return *_attr; }
|
NameDict& attr() noexcept { return *_attr; }
|
||||||
PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
|
PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
|
||||||
virtual void* value() = 0;
|
virtual void* value() = 0;
|
||||||
virtual void _mark() = 0;
|
virtual void _obj_gc_mark() = 0;
|
||||||
|
|
||||||
PyObject(Type type) : type(type) {}
|
PyObject(Type type) : type(type) {}
|
||||||
virtual ~PyObject() { delete _attr; }
|
virtual ~PyObject() { delete _attr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void _mark(T& t);
|
void _gc_mark(T& t);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct Py_ : PyObject {
|
struct Py_ : PyObject {
|
||||||
@ -136,16 +138,16 @@ struct Py_ : PyObject {
|
|||||||
}
|
}
|
||||||
void* value() override { return &_value; }
|
void* value() override { return &_value; }
|
||||||
|
|
||||||
void _mark() override {
|
void _obj_gc_mark() override {
|
||||||
if(gc.marked) return;
|
if(gc.marked) return;
|
||||||
gc.marked = true;
|
gc.marked = true;
|
||||||
if(_attr != nullptr) _attr->_mark();
|
if(_attr != nullptr) _attr->_gc_mark();
|
||||||
pkpy::_mark<T>(_value); // handle PyObject* inside _value `T`
|
pkpy::_gc_mark<T>(_value); // handle PyObject* inside _value `T`
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
|
#define OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
|
||||||
#define OBJ_MARK(obj) if(!is_tagged(obj)) obj->_mark()
|
#define OBJ_MARK(obj) if(!is_tagged(obj)) obj->_obj_gc_mark()
|
||||||
|
|
||||||
#if DEBUG_NO_BUILTIN_MODULES
|
#if DEBUG_NO_BUILTIN_MODULES
|
||||||
#define OBJ_NAME(obj) Str("<?>")
|
#define OBJ_NAME(obj) Str("<?>")
|
||||||
|
10
src/vm.h
10
src/vm.h
@ -36,7 +36,7 @@ public:
|
|||||||
: BaseIter(vm), frame(std::move(frame)), state(0) {}
|
: BaseIter(vm), frame(std::move(frame)), state(0) {}
|
||||||
|
|
||||||
PyObject* next() override;
|
PyObject* next() override;
|
||||||
void _mark() override;
|
void _gc_mark() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PyTypeInfo{
|
struct PyTypeInfo{
|
||||||
@ -166,7 +166,7 @@ public:
|
|||||||
if(_module == nullptr) _module = _main;
|
if(_module == nullptr) _module = _main;
|
||||||
try {
|
try {
|
||||||
CodeObject_ code = compile(source, filename, mode);
|
CodeObject_ code = compile(source, filename, mode);
|
||||||
#if DEBUG_DIS_EXEC_REPL
|
#if DEBUG_DIS_EXEC
|
||||||
if(_module == _main) std::cout << disassemble(code) << '\n';
|
if(_module == _main) std::cout << disassemble(code) << '\n';
|
||||||
#endif
|
#endif
|
||||||
return _exec(code, _module, builtins);
|
return _exec(code, _module, builtins);
|
||||||
@ -615,7 +615,7 @@ inline Str VM::disassemble(CodeObject_ co){
|
|||||||
if(i != co->codes.size() - 1) ss << '\n';
|
if(i != co->codes.size() - 1) ss << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !DEBUG_DIS_EXEC_REPL_MIN
|
#if !DEBUG_DIS_EXEC_MIN
|
||||||
StrStream consts;
|
StrStream consts;
|
||||||
consts << "co_consts: ";
|
consts << "co_consts: ";
|
||||||
consts << CAST(Str, asRepr(VAR(co->consts)));
|
consts << CAST(Str, asRepr(VAR(co->consts)));
|
||||||
@ -909,9 +909,7 @@ inline PyObject* VM::_exec(){
|
|||||||
|
|
||||||
inline void ManagedHeap::mark(VM *vm) {
|
inline void ManagedHeap::mark(VM *vm) {
|
||||||
for(PyObject* obj: _no_gc) OBJ_MARK(obj);
|
for(PyObject* obj: _no_gc) OBJ_MARK(obj);
|
||||||
for(auto& frame : vm->callstack.data()){
|
for(auto& frame : vm->callstack.data()) frame->_gc_mark();
|
||||||
frame->_mark();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ManagedHeap::_delete_hook(VM *vm, PyObject *obj){
|
inline void ManagedHeap::_delete_hook(VM *vm, PyObject *obj){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user