blueloveTH 3 лет назад
Родитель
Сommit
08601671dc
3 измененных файлов с 20 добавлено и 22 удалено
  1. 13 15
      src/memory.h
  2. 2 2
      src/obj.h
  3. 5 5
      src/vm.h

+ 13 - 15
src/memory.h

@@ -19,8 +19,11 @@ namespace pkpy{
     };
 
     template <typename T>
-    class shared_ptr {
-        int* counter;
+    struct shared_ptr {
+        union {
+            int* counter;
+            i64 bits;
+        };
 
 #define _t() (T*)(counter + 1)
 #define _inc_counter() if(!is_tagged() && counter) ++(*counter)
@@ -74,20 +77,14 @@ namespace pkpy{
             counter = nullptr;
         }
 
-        template <typename __VAL>
-        inline __VAL cast() const {
-            static_assert(std::is_same_v<T, PyObject>, "T must be PyObject");
-            return reinterpret_cast<__VAL>(counter);
-        }
-
         inline constexpr bool is_tagged() const {
             if constexpr(!std::is_same_v<T, PyObject>) return false;
-            return (reinterpret_cast<i64>(counter) & 0b11) != 0b00;
+            return (bits & 0b11) != 0b00;
         }
-        inline bool is_tag_00() const { return (reinterpret_cast<i64>(counter) & 0b11) == 0b00; }
-        inline bool is_tag_01() const { return (reinterpret_cast<i64>(counter) & 0b11) == 0b01; }
-        inline bool is_tag_10() const { return (reinterpret_cast<i64>(counter) & 0b11) == 0b10; }
-        inline bool is_tag_11() const { return (reinterpret_cast<i64>(counter) & 0b11) == 0b11; }
+        inline bool is_tag_00() const { return (bits & 0b11) == 0b00; }
+        inline bool is_tag_01() const { return (bits & 0b11) == 0b01; }
+        inline bool is_tag_10() const { return (bits & 0b11) == 0b10; }
+        inline bool is_tag_11() const { return (bits & 0b11) == 0b11; }
     };
 
 #undef _t
@@ -112,8 +109,9 @@ namespace pkpy{
     }
 };
 
-static_assert(sizeof(i64) == sizeof(pkpy::shared_ptr<PyObject>));
-static_assert(sizeof(f64) == sizeof(pkpy::shared_ptr<PyObject>));
+static_assert(sizeof(i64) == sizeof(int*));
+static_assert(sizeof(f64) == sizeof(int*));
+static_assert(sizeof(pkpy::shared_ptr<PyObject>) == sizeof(int*));
 static_assert(std::numeric_limits<float>::is_iec559);
 static_assert(std::numeric_limits<double>::is_iec559);
 

+ 2 - 2
src/obj.h

@@ -124,11 +124,11 @@ inline bool is_type(const PyVar& obj, Type type) noexcept {
 }
 
 inline bool is_both_int_or_float(const PyVar& a, const PyVar& b) noexcept {
-    return ((a.cast<i64>() | b.cast<i64>()) & 0b11) != 0b00;
+    return ((a.bits | b.bits) & 0b11) != 0b00;
 }
 
 inline bool is_both_int(const PyVar& a, const PyVar& b) noexcept {
-    return (a.cast<i64>() & b.cast<i64>() & 0b11) == 0b01;
+    return (a.bits & b.bits & 0b11) == 0b01;
 }
 
 inline bool is_int(const PyVar& obj) noexcept {

+ 5 - 5
src/vm.h

@@ -554,11 +554,11 @@ public:
 
     inline i64 PyInt_AS_C(const PyVar& obj){
         check_type(obj, tp_int);
-        return obj.cast<i64>() >> 2;
+        return obj.bits >> 2;
     }
 
     inline i64 _PyInt_AS_C(const PyVar& obj){
-        return obj.cast<i64>() >> 2;
+        return obj.bits >> 2;
     }
 
     inline PyVar PyFloat(f64 value) {
@@ -570,13 +570,13 @@ public:
 
     inline f64 PyFloat_AS_C(const PyVar& obj){
         check_type(obj, tp_float);
-        i64 bits = obj.cast<i64>();
+        i64 bits = obj.bits;
         bits = (bits >> 2) << 2;
         return __8B(bits)._float;
     }
 
     inline f64 _PyFloat_AS_C(const PyVar& obj){
-        i64 bits = obj.cast<i64>();
+        i64 bits = obj.bits;
         bits = (bits >> 2) << 2;
         return __8B(bits)._float;
     }
@@ -663,7 +663,7 @@ public:
             }
             return x;
         }
-        if (is_type(obj, tp_type)) return obj.cast<i64>();
+        if (is_type(obj, tp_type)) return obj.bits;
         if (is_type(obj, tp_bool)) return PyBool_AS_C(obj) ? 1 : 0;
         if (is_float(obj)){
             f64 val = PyFloat_AS_C(obj);