blueloveTH 1 سال پیش
والد
کامیت
a8b92c0ff4
4فایلهای تغییر یافته به همراه29 افزوده شده و 45 حذف شده
  1. 2 2
      include/pocketpy/cffi.h
  2. 8 6
      include/pocketpy/gc.h
  3. 1 1
      include/pocketpy/linalg.h
  4. 18 36
      include/pocketpy/obj.h

+ 2 - 2
include/pocketpy/cffi.h

@@ -87,8 +87,8 @@ struct Struct{
     static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
-static_assert(sizeof(Py_<Struct>) <= 64);
-static_assert(sizeof(Py_<Tuple>) <= 128);
+static_assert(py_sizeof<Struct> <= 64);
+static_assert(py_sizeof<Tuple> <= 128);
 
 /***********************************************/
 template<typename Tp>

+ 8 - 6
include/pocketpy/gc.h

@@ -40,10 +40,11 @@ struct ManagedHeap{
 
     template<typename T, typename... Args>
     PyVar gcnew(Type type, Args&&... args){
-        using __T = Py_<std::decay_t<T>>;
-        static_assert(!is_sso_v<std::decay_t<T>>, "gcnew cannot be used with SSO types");
+        using __T = std::decay_t<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::decay_t<T>>(std::forward<Args>(args)...);
+        PyObject* p = new(pool128_alloc(py_sizeof<__T>)) PyObject();
+        p->placement_new<__T>(std::forward<Args>(args)...);
         PyVar obj(type, p);
         gen.push_back(obj);
         gc_counter++;
@@ -52,9 +53,10 @@ struct ManagedHeap{
 
     template<typename T, typename... Args>
     PyVar _new(Type type, Args&&... args){
-        using __T = Py_<std::decay_t<T>>;
-        static_assert(!is_sso_v<std::decay_t<T>>);
-        PyObject* p = new(pool128_alloc<__T>()) Py_<std::decay_t<T>>(std::forward<Args>(args)...);
+        using __T = std::decay_t<T>;
+        static_assert(!is_sso_v<__T>);
+        PyObject* p = new(pool128_alloc<__T>()) PyObject();
+        p->placement_new<__T>(std::forward<Args>(args)...);
         PyVar obj(type, p);
         obj->gc_enabled = false;
         _no_gc.push_back(obj);

+ 1 - 1
include/pocketpy/linalg.h

@@ -122,7 +122,7 @@ struct Mat3x3{
 
 void add_module_linalg(VM* vm);
 
-static_assert(sizeof(Py_<Mat3x3>) <= 64);
+static_assert(py_sizeof<Mat3x3> <= 64);
 static_assert(is_pod_v<Vec2>);
 static_assert(is_pod_v<Vec3>);
 static_assert(is_pod_v<Vec4>);

+ 18 - 36
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<typename T, typename ...Args>
+    void placement_new(Args&&... args){
+        static_assert(std::is_same_v<T, std::decay_t<T>>);
+        new(_value_ptr()) T(std::forward<Args>(args)...);
+
+        // backdoor for important builtin types
+        if constexpr(std::is_same_v<T, DummyInstance>){
+            _enable_instance_dict();
+        }else if constexpr(std::is_same_v<T, Type>){
+            _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR);
+        }else if constexpr(std::is_same_v<T, DummyModule>){
+            _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR);
+        }
+    }
+
     void _enable_instance_dict() {
         _attr = new(pool128_alloc<NameDict>()) NameDict();
     }
-
     void _enable_instance_dict(float lf){
         _attr = new(pool128_alloc<NameDict>()) NameDict(lf);
     }
@@ -149,15 +162,6 @@ inline bool is_type(PyVar obj, Type type) {
 template <typename, typename=void> struct has_gc_marker : std::false_type {};
 template <typename T> struct has_gc_marker<T, std::void_t<decltype(&T::_gc_mark)>> : std::true_type {};
 
-template <typename T>
-struct Py_ final: PyObject {
-    static_assert(!std::is_reference_v<T>);
-    static_assert(!is_sso_v<T>);
-    T _value;
-    template <typename... Args>
-    Py_(Args&&... args) : PyObject(), _value(std::forward<Args>(args)...) { }
-};
-
 struct MappingProxy{
     PyVar obj;
     MappingProxy(PyVar obj) : obj(obj) {}
@@ -176,7 +180,8 @@ obj_get_t<T> PyVar::obj_get(){
         return as<T>();
     }else{
         PK_DEBUG_ASSERT(!is_sso)
-        return ((Py_<T>*)(_1))->_value;
+        void* v = ((PyObject*)_1)->_value_ptr();
+        return *reinterpret_cast<T*>(v);
     }
 }
 
@@ -203,29 +208,6 @@ inline bool try_cast_int(PyVar obj, i64* val) noexcept {
     return false;
 }
 
-
-template<>
-struct Py_<DummyInstance> final: PyObject {
-    Py_(): PyObject() {
-        _enable_instance_dict();
-    }
-};
-
-template<>
-struct Py_<Type> final: PyObject {
-    Type _value;
-    Py_(Type val): PyObject(), _value(val) {
-        _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR);
-    }
-};
-
-template<>
-struct Py_<DummyModule> 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;