blueloveTH 3 years ago
parent
commit
1c6ea53050
3 changed files with 9 additions and 18 deletions
  1. 1 9
      src/common.h
  2. 6 8
      src/obj.h
  3. 2 1
      src/vm.h

+ 1 - 9
src/common.h

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

+ 6 - 8
src/obj.h

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

+ 2 - 1
src/vm.h

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