fix a bug

This commit is contained in:
blueloveTH 2023-04-06 15:25:13 +08:00
parent 352688e9ae
commit 6b9b5945a3
8 changed files with 43 additions and 41 deletions

View File

@ -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

View File

@ -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

View File

@ -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();
} }
}; };

View File

@ -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

View File

@ -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();
} }
} }

View File

@ -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
}; };

View File

@ -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("<?>")

View File

@ -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){