From e3844074944581f99188562b58b484106dd28c81 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 29 Apr 2023 14:14:28 +0800 Subject: [PATCH] ... --- src/cffi.h | 81 +++++------------------ src/gc.h | 46 ------------- src/obj.h | 189 ++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 161 insertions(+), 155 deletions(-) diff --git a/src/cffi.h b/src/cffi.h index 45c1a920..6f97688b 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -5,72 +5,25 @@ namespace pkpy { -// template -// struct NativeProxyFunc { -// static constexpr int N = sizeof...(Params); -// using _Fp = Ret(*)(Params...); -// _Fp func; -// NativeProxyFunc(_Fp func) : func(func) {} +#define PY_CLASS(T, mod, name) \ + static Type _type(VM* vm) { \ + static const StrName __x0(#mod); \ + static const StrName __x1(#name); \ + return OBJ_GET(Type, vm->_modules[__x0]->attr(__x1)); \ + } \ + static PyObject* register_class(VM* vm, PyObject* mod) { \ + PyObject* type = vm->new_type_object(mod, #name, vm->tp_object); \ + if(OBJ_NAME(mod) != #mod) { \ + auto msg = fmt("register_class() failed: ", OBJ_NAME(mod), " != ", #mod); \ + throw std::runtime_error(msg); \ + } \ + T::_register(vm, mod, type); \ + type->attr()._try_perfect_rehash(); \ + return type; \ + } -// PyObject* operator()(VM* vm, ArgsView args) { -// if (args.size() != N) { -// vm->TypeError("expected " + std::to_string(N) + " arguments, but got " + std::to_string(args.size())); -// } -// return call(vm, args, std::make_index_sequence()); -// } +#define VAR_T(T, ...) vm->heap.gcnew(T::_type(vm), T(__VA_ARGS__)) -// template -// std::enable_if_t, PyObject*> call(VM* vm, ArgsView args, std::index_sequence) { -// func(py_cast(vm, args[Is])...); -// return vm->None; -// } - -// template -// std::enable_if_t, PyObject*> call(VM* vm, ArgsView args, std::index_sequence) { -// __Ret ret = func(py_cast(vm, args[Is])...); -// return VAR(std::move(ret)); -// } -// }; - -// template -// struct NativeProxyMethod { -// static constexpr int N = sizeof...(Params); -// using _Fp = Ret(T::*)(Params...); -// _Fp func; -// NativeProxyMethod(_Fp func) : func(func) {} - -// PyObject* operator()(VM* vm, ArgsView args) { -// int actual_size = args.size() - 1; -// if (actual_size != N) { -// vm->TypeError("expected " + std::to_string(N) + " arguments, but got " + std::to_string(actual_size)); -// } -// return call(vm, args, std::make_index_sequence()); -// } - -// template -// std::enable_if_t, PyObject*> call(VM* vm, ArgsView args, std::index_sequence) { -// T& self = py_cast(vm, args[0]); -// (self.*func)(py_cast(vm, args[Is+1])...); -// return vm->None; -// } - -// template -// std::enable_if_t, PyObject*> call(VM* vm, ArgsView args, std::index_sequence) { -// T& self = py_cast(vm, args[0]); -// __Ret ret = (self.*func)(py_cast(vm, args[Is+1])...); -// return VAR(std::move(ret)); -// } -// }; - -// template -// auto native_proxy_callable(Ret(*func)(Params...)) { -// return NativeProxyFunc(func); -// } - -// template -// auto native_proxy_callable(Ret(T::*func)(Params...)) { -// return NativeProxyMethod(func); -// } struct VoidP{ PY_CLASS(VoidP, c, void_p) diff --git a/src/gc.h b/src/gc.h index f6bb15c8..07567b16 100644 --- a/src/gc.h +++ b/src/gc.h @@ -116,50 +116,4 @@ inline void FuncDecl::_gc_mark() const{ for(int i=0; i inline void gc_mark(List& t){ - for(PyObject* obj: t){ - OBJ_MARK(obj); - } -} - -template<> inline void gc_mark(Tuple& t){ - for(PyObject* obj: t){ - OBJ_MARK(obj); - } -} - -template<> inline void gc_mark(NameDict& t){ - if(t.size() == 0) return; - for(uint16_t i=0; i inline void gc_mark(MappingProxy& t){ - OBJ_MARK(t.obj); -} - -template<> inline void gc_mark(BoundMethod& t){ - OBJ_MARK(t.self); - OBJ_MARK(t.func); -} - -template<> inline void gc_mark(Slice& t){ - OBJ_MARK(t.start); - OBJ_MARK(t.stop); - OBJ_MARK(t.step); -} - -template<> inline void gc_mark(Function& t){ - t.decl->_gc_mark(); - if(t._module != nullptr) OBJ_MARK(t._module); - if(t._closure != nullptr) gc_mark(*t._closure); -} - -template<> inline void gc_mark(Super& t){ - OBJ_MARK(t.first); -} -// NOTE: std::function may capture some PyObject*, they can not be marked - } // namespace pkpy \ No newline at end of file diff --git a/src/obj.h b/src/obj.h index 515fcf73..ffcf2ba7 100644 --- a/src/obj.h +++ b/src/obj.h @@ -115,7 +115,8 @@ struct PyObject{ virtual void* value() = 0; virtual void _obj_gc_mark() = 0; - PyObject(Type type) : type(type) {} + PyObject(Type type) : type(type), _attr(nullptr) {} + virtual ~PyObject() { if(_attr == nullptr) return; _attr->~NameDict(); @@ -127,35 +128,13 @@ struct PyObject{ } }; -template -void gc_mark(T& t); - template struct Py_ final: PyObject { T _value; - - Py_(Type type, const T& val): PyObject(type), _value(val) { _init(); } - Py_(Type type, T&& val): PyObject(type), _value(std::move(val)) { _init(); } - - void _init() noexcept { - if constexpr (std::is_same_v || std::is_same_v) { - _attr = new(pool64.alloc()) NameDict(kTypeAttrLoadFactor); - }else if constexpr(std::is_same_v){ - _attr = new(pool64.alloc()) NameDict(kInstAttrLoadFactor); - }else if constexpr(std::is_same_v || std::is_same_v){ - _attr = new(pool64.alloc()) NameDict(kInstAttrLoadFactor); - }else{ - _attr = nullptr; - } - } void* value() override { return &_value; } - - void _obj_gc_mark() override { - if(gc.marked) return; - gc.marked = true; - if(_attr != nullptr) pkpy::gc_mark(*_attr); - pkpy::gc_mark(_value); // handle PyObject* inside _value `T` - } + void _obj_gc_mark() override {} + Py_(Type type, const T& value) : PyObject(type), _value(value) {} + Py_(Type type, T&& value) : PyObject(type), _value(std::move(value)) {} }; struct MappingProxy{ @@ -166,7 +145,22 @@ struct MappingProxy{ }; #define OBJ_GET(T, obj) (((Py_*)(obj))->_value) -#define OBJ_MARK(obj) if(!is_tagged(obj)) (obj)->_obj_gc_mark() +// #define OBJ_GET(T, obj) (*reinterpret_cast((obj)->value())) + +#define OBJ_MARK(obj) \ + if(!is_tagged(obj) && !(obj)->gc.marked) { \ + (obj)->gc.marked = true; \ + (obj)->_obj_gc_mark(); \ + if((obj)->is_attr_valid()) gc_mark_namedict((obj)->attr()); \ + } + +inline void gc_mark_namedict(NameDict& t){ + if(t.size() == 0) return; + for(uint16_t i=0; itype == type; } -#define PY_CLASS(T, mod, name) \ - static Type _type(VM* vm) { \ - static const StrName __x0(#mod); \ - static const StrName __x1(#name); \ - return OBJ_GET(Type, vm->_modules[__x0]->attr(__x1)); \ - } \ - static PyObject* register_class(VM* vm, PyObject* mod) { \ - PyObject* type = vm->new_type_object(mod, #name, vm->tp_object); \ - if(OBJ_NAME(mod) != #mod) { \ - auto msg = fmt("register_class() failed: ", OBJ_NAME(mod), " != ", #mod); \ - throw std::runtime_error(msg); \ - } \ - T::_register(vm, mod, type); \ - type->attr()._try_perfect_rehash(); \ - return type; \ - } - union BitsCvt { i64 _int; f64 _float; @@ -255,8 +232,130 @@ __T _py_cast(VM* vm, PyObject* obj) { } #define VAR(x) py_var(vm, x) -#define VAR_T(T, ...) vm->heap.gcnew(T::_type(vm), T(__VA_ARGS__)) #define CAST(T, x) py_cast(vm, x) #define _CAST(T, x) _py_cast(vm, x) +/*****************************************************************/ +template<> +struct Py_ final: PyObject { + List _value; + void* value() override { return &_value; } + + Py_(Type type, List&& val): PyObject(type), _value(std::move(val)) {} + Py_(Type type, const List& val): PyObject(type), _value(val) {} + + void _obj_gc_mark() override { + for(PyObject* obj: _value) OBJ_MARK(obj); + } +}; + +template<> +struct Py_ final: PyObject { + Tuple _value; + void* value() override { return &_value; } + + Py_(Type type, Tuple&& val): PyObject(type), _value(std::move(val)) {} + Py_(Type type, const Tuple& val): PyObject(type), _value(val) {} + + void _obj_gc_mark() override { + for(PyObject* obj: _value) OBJ_MARK(obj); + } +}; + +template<> +struct Py_ final: PyObject { + MappingProxy _value; + void* value() override { return &_value; } + Py_(Type type, MappingProxy val): PyObject(type), _value(val) {} + void _obj_gc_mark() override { + OBJ_MARK(_value.obj); + } +}; + +template<> +struct Py_ final: PyObject { + BoundMethod _value; + void* value() override { return &_value; } + Py_(Type type, BoundMethod val): PyObject(type), _value(val) {} + void _obj_gc_mark() override { + OBJ_MARK(_value.self); + OBJ_MARK(_value.func); + } +}; + +template<> +struct Py_ final: PyObject { + Slice _value; + void* value() override { return &_value; } + Py_(Type type, Slice val): PyObject(type), _value(val) {} + void _obj_gc_mark() override { + OBJ_MARK(_value.start); + OBJ_MARK(_value.stop); + OBJ_MARK(_value.step); + } +}; + +template<> +struct Py_ final: PyObject { + Function _value; + void* value() override { return &_value; } + Py_(Type type, Function val): PyObject(type), _value(val) { + enable_instance_dict(); + } + void _obj_gc_mark() override { + _value.decl->_gc_mark(); + if(_value._module != nullptr) OBJ_MARK(_value._module); + if(_value._closure != nullptr) gc_mark_namedict(*_value._closure); + } +}; + +template<> +struct Py_ final: PyObject { + NativeFunc _value; + void* value() override { return &_value; } + Py_(Type type, NativeFunc val): PyObject(type), _value(val) { + enable_instance_dict(); + } + void _obj_gc_mark() override {} +}; + +template<> +struct Py_ final: PyObject { + Super _value; + void* value() override { return &_value; } + Py_(Type type, Super val): PyObject(type), _value(val) {} + void _obj_gc_mark() override { + OBJ_MARK(_value.first); + } +}; + +template<> +struct Py_ final: PyObject { + void* value() override { return nullptr; } + Py_(Type type, DummyInstance val): PyObject(type) { + enable_instance_dict(); + } + void _obj_gc_mark() override {} +}; + +template<> +struct Py_ final: PyObject { + Type _value; + void* value() override { return &_value; } + Py_(Type type, Type val): PyObject(type), _value(val) { + enable_instance_dict(kTypeAttrLoadFactor); + } + void _obj_gc_mark() override {} +}; + +template<> +struct Py_ final: PyObject { + void* value() override { return nullptr; } + Py_(Type type, DummyModule val): PyObject(type) { + enable_instance_dict(kTypeAttrLoadFactor); + } + void _obj_gc_mark() override {} +}; + + } // namespace pkpy \ No newline at end of file