This commit is contained in:
blueloveTH 2023-02-10 15:54:53 +08:00
parent c35eff5a21
commit 1c6ea53050
3 changed files with 9 additions and 18 deletions

View File

@ -39,17 +39,9 @@ typedef double f64;
struct Dummy { char _; };
#define DUMMY_VAL Dummy()
#define DUMMY_VAL_TP Dummy
template<typename T>
void* tid() {
static volatile int8_t _x;
return (void*)(&_x);
}
// This does not ensure to be unique when the pointer of obj->type is deleted & reused.
// But it is good enough for now.
template<typename T>
inline void* obj_tid(void* alt) { return tid<T>(); }
template<>
inline void* obj_tid<Dummy>(void* alt) { return alt; }
}

View File

@ -76,12 +76,12 @@ typedef pkpy::shared_ptr<Function> _Func;
struct PyObject {
PyVar type;
PyVarDict attribs;
void* _tid;
inline bool is_type(const PyVar& type) const noexcept{ return this->type == type; }
virtual void* value() = 0;
virtual void* type_id() = 0;
PyObject(const PyVar& type) : type(type) {}
PyObject(const PyVar& type, void* _tid) : type(type), _tid(_tid) {}
virtual ~PyObject() = default;
};
@ -89,13 +89,11 @@ template <typename T>
struct Py_ : PyObject {
T _value;
Py_(const PyVar& type, T val) : PyObject(type), _value(val) {}
Py_(const PyVar& type, T val) : PyObject(type, tid<T>()), _value(val) {}
void* value() override { return &_value; }
void* type_id() override { return obj_tid<T>((void*)type.get()); }
};
// Unsafe cast from PyObject to C++ type
#define OBJ_GET(T, obj) (*static_cast<T*>((obj)->value()))
#define OBJ_GET(T, obj) (((Py_<T>*)((obj).get()))->_value)
#define OBJ_NAME(obj) OBJ_GET(_Str, (obj)->attribs[__name__])
#define OBJ_TP_NAME(obj) OBJ_GET(_Str, (obj)->type->attribs[__name__])
@ -113,8 +111,8 @@ namespace pkpy {
struct sp_deleter<PyObject> {
inline static void call(int* counter) {
PyObject* obj = (PyObject*)(counter + 1);
std::vector<int*>& pool = _obj_pool[obj->type_id()];
if(pool.size() > 60){
std::vector<int*>& pool = _obj_pool[obj->_tid];
if(obj->_tid==tid<Dummy>() || pool.size() > 60){
obj->~PyObject();
free(counter);
}else{

View File

@ -596,7 +596,8 @@ public:
template<typename T>
inline PyVar new_object(PyVar type, T _value) {
if(!type->is_type(_tp_type)) UNREACHABLE();
std::vector<int*>& pool = _obj_pool[obj_tid<T>((void*)type.get())];
if constexpr (std::is_same_v<T, Dummy>) return pkpy::make_shared<PyObject, Py_<T>>(type, _value);
std::vector<int*>& pool = _obj_pool[tid<T>()];
if(pool.empty()) return pkpy::make_shared<PyObject, Py_<T>>(type, _value);
int* counter = pool.back(); pool.pop_back();
*counter = 1;