diff --git a/src/memory.h b/src/memory.h index 65560dc0..c1b26f47 100644 --- a/src/memory.h +++ b/src/memory.h @@ -19,8 +19,11 @@ namespace pkpy{ }; template - 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 - inline __VAL cast() const { - static_assert(std::is_same_v, "T must be PyObject"); - return reinterpret_cast<__VAL>(counter); - } - inline constexpr bool is_tagged() const { if constexpr(!std::is_same_v) return false; - return (reinterpret_cast(counter) & 0b11) != 0b00; + return (bits & 0b11) != 0b00; } - inline bool is_tag_00() const { return (reinterpret_cast(counter) & 0b11) == 0b00; } - inline bool is_tag_01() const { return (reinterpret_cast(counter) & 0b11) == 0b01; } - inline bool is_tag_10() const { return (reinterpret_cast(counter) & 0b11) == 0b10; } - inline bool is_tag_11() const { return (reinterpret_cast(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)); -static_assert(sizeof(f64) == sizeof(pkpy::shared_ptr)); +static_assert(sizeof(i64) == sizeof(int*)); +static_assert(sizeof(f64) == sizeof(int*)); +static_assert(sizeof(pkpy::shared_ptr) == sizeof(int*)); static_assert(std::numeric_limits::is_iec559); static_assert(std::numeric_limits::is_iec559); diff --git a/src/obj.h b/src/obj.h index 72c28790..2b6282c8 100644 --- a/src/obj.h +++ b/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() | b.cast()) & 0b11) != 0b00; + return ((a.bits | b.bits) & 0b11) != 0b00; } inline bool is_both_int(const PyVar& a, const PyVar& b) noexcept { - return (a.cast() & b.cast() & 0b11) == 0b01; + return (a.bits & b.bits & 0b11) == 0b01; } inline bool is_int(const PyVar& obj) noexcept { diff --git a/src/vm.h b/src/vm.h index 20776a75..70e78bc2 100644 --- a/src/vm.h +++ b/src/vm.h @@ -554,11 +554,11 @@ public: inline i64 PyInt_AS_C(const PyVar& obj){ check_type(obj, tp_int); - return obj.cast() >> 2; + return obj.bits >> 2; } inline i64 _PyInt_AS_C(const PyVar& obj){ - return obj.cast() >> 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 bits = obj.bits; bits = (bits >> 2) << 2; return __8B(bits)._float; } inline f64 _PyFloat_AS_C(const PyVar& obj){ - i64 bits = obj.cast(); + 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(); + 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);