diff --git a/include/pocketpy/cffi.h b/include/pocketpy/cffi.h index cca04c41..35a8834c 100644 --- a/include/pocketpy/cffi.h +++ b/include/pocketpy/cffi.h @@ -87,8 +87,8 @@ struct Struct{ static void _register(VM* vm, PyVar mod, PyVar type); }; -static_assert(sizeof(Py_) <= 64); -static_assert(sizeof(Py_) <= 128); +static_assert(py_sizeof <= 64); +static_assert(py_sizeof <= 128); /***********************************************/ template diff --git a/include/pocketpy/gc.h b/include/pocketpy/gc.h index 5f3dd6a7..9c468197 100644 --- a/include/pocketpy/gc.h +++ b/include/pocketpy/gc.h @@ -40,10 +40,11 @@ struct ManagedHeap{ template PyVar gcnew(Type type, Args&&... args){ - using __T = Py_>; - static_assert(!is_sso_v>, "gcnew cannot be used with SSO types"); + using __T = std::decay_t; + static_assert(!is_sso_v<__T>, "gcnew cannot be used with SSO types"); // https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476 - PyObject* p = new(pool128_alloc<__T>()) Py_>(std::forward(args)...); + PyObject* p = new(pool128_alloc(py_sizeof<__T>)) PyObject(); + p->placement_new<__T>(std::forward(args)...); PyVar obj(type, p); gen.push_back(obj); gc_counter++; @@ -52,9 +53,10 @@ struct ManagedHeap{ template PyVar _new(Type type, Args&&... args){ - using __T = Py_>; - static_assert(!is_sso_v>); - PyObject* p = new(pool128_alloc<__T>()) Py_>(std::forward(args)...); + using __T = std::decay_t; + static_assert(!is_sso_v<__T>); + PyObject* p = new(pool128_alloc<__T>()) PyObject(); + p->placement_new<__T>(std::forward(args)...); PyVar obj(type, p); obj->gc_enabled = false; _no_gc.push_back(obj); diff --git a/include/pocketpy/linalg.h b/include/pocketpy/linalg.h index f65743d7..67204816 100644 --- a/include/pocketpy/linalg.h +++ b/include/pocketpy/linalg.h @@ -122,7 +122,7 @@ struct Mat3x3{ void add_module_linalg(VM* vm); -static_assert(sizeof(Py_) <= 64); +static_assert(py_sizeof <= 64); static_assert(is_pod_v); static_assert(is_pod_v); static_assert(is_pod_v); diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index 75287bc6..5e4e18fc 100644 --- a/include/pocketpy/obj.h +++ b/include/pocketpy/obj.h @@ -106,9 +106,8 @@ struct PyObject{ bool gc_marked; // whether this object is marked NameDict* _attr; - void* _value_ptr() noexcept { return 1 + &_attr; } - bool is_attr_valid() const noexcept { return _attr != nullptr; } + void* _value_ptr() noexcept { return 1 + &_attr; } NameDict& attr() { PK_DEBUG_ASSERT(is_attr_valid()) @@ -122,10 +121,24 @@ struct PyObject{ PyObject() : gc_enabled(true), gc_marked(false), _attr(nullptr) {} + template + void placement_new(Args&&... args){ + static_assert(std::is_same_v>); + new(_value_ptr()) T(std::forward(args)...); + + // backdoor for important builtin types + if constexpr(std::is_same_v){ + _enable_instance_dict(); + }else if constexpr(std::is_same_v){ + _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); + }else if constexpr(std::is_same_v){ + _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); + } + } + void _enable_instance_dict() { _attr = new(pool128_alloc()) NameDict(); } - void _enable_instance_dict(float lf){ _attr = new(pool128_alloc()) NameDict(lf); } @@ -149,15 +162,6 @@ inline bool is_type(PyVar obj, Type type) { template struct has_gc_marker : std::false_type {}; template struct has_gc_marker> : std::true_type {}; -template -struct Py_ final: PyObject { - static_assert(!std::is_reference_v); - static_assert(!is_sso_v); - T _value; - template - Py_(Args&&... args) : PyObject(), _value(std::forward(args)...) { } -}; - struct MappingProxy{ PyVar obj; MappingProxy(PyVar obj) : obj(obj) {} @@ -176,7 +180,8 @@ obj_get_t PyVar::obj_get(){ return as(); }else{ PK_DEBUG_ASSERT(!is_sso) - return ((Py_*)(_1))->_value; + void* v = ((PyObject*)_1)->_value_ptr(); + return *reinterpret_cast(v); } } @@ -203,29 +208,6 @@ inline bool try_cast_int(PyVar obj, i64* val) noexcept { return false; } - -template<> -struct Py_ final: PyObject { - Py_(): PyObject() { - _enable_instance_dict(); - } -}; - -template<> -struct Py_ final: PyObject { - Type _value; - Py_(Type val): PyObject(), _value(val) { - _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); - } -}; - -template<> -struct Py_ final: PyObject { - Py_(): PyObject() { - _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR); - } -}; - extern PyVar const PY_NULL; extern PyVar const PY_OP_CALL; extern PyVar const PY_OP_YIELD;