1
0
Эх сурвалжийг харах

`gcnew` constructs `PyObject` inplace, no `std::move` any more!

blueloveTH 2 жил өмнө
parent
commit
ed669b4069

+ 1 - 1
include/pocketpy/cffi.h

@@ -27,7 +27,7 @@ namespace pkpy {
         return type;                                                        \
     }                                                                       
 
-#define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), T(__VA_ARGS__))
+#define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), __VA_ARGS__)
 
 int c99_sizeof(VM*, const Str&);
 

+ 5 - 3
include/pocketpy/codeobject.h

@@ -129,7 +129,7 @@ struct FuncDecl {
 };
 
 struct UserData{
-    char data[16];
+    char data[15];
     bool empty;
 
     UserData(): empty(true) {}
@@ -186,7 +186,8 @@ struct Function{
 template<>
 struct Py_<Function> final: PyObject {
     Function _value;
-    Py_(Type type, Function val): PyObject(type), _value(val) {
+    template<typename... Args>
+    Py_(Type type, Args&&... args): PyObject(type), _value(std::forward<Args>(args)...) {
         enable_instance_dict();
     }
     void _obj_gc_mark() override {
@@ -199,7 +200,8 @@ struct Py_<Function> final: PyObject {
 template<>
 struct Py_<NativeFunc> final: PyObject {
     NativeFunc _value;
-    Py_(Type type, NativeFunc val): PyObject(type), _value(val) {
+    template<typename... Args>
+    Py_(Type type, Args&&... args): PyObject(type), _value(std::forward<Args>(args)...) {
         enable_instance_dict();
     }
     void _obj_gc_mark() override {

+ 6 - 14
include/pocketpy/gc.h

@@ -37,29 +37,21 @@ struct ManagedHeap{
     }
     /********************/
 
-    template<typename T>
-    PyObject* gcnew(Type type, T&& val){
+    template<typename T, typename... Args>
+    PyObject* gcnew(Type type, Args&&... args){
         using __T = Py_<std::decay_t<T>>;
-#if _WIN32
         // https://github.com/blueloveTH/pocketpy/issues/94#issuecomment-1594784476
-        PyObject* obj = new(pool64.alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<T>(val));
-#else
-        PyObject* obj = new(pool64.alloc<__T>()) __T(type, std::forward<T>(val));
-#endif
+        PyObject* obj = new(pool64.alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
         gen.push_back(obj);
         gc_counter++;
         return obj;
     }
 
-    template<typename T>
-    PyObject* _new(Type type, T&& val){
+    template<typename T, typename... Args>
+    PyObject* _new(Type type, Args&&... args){
         using __T = Py_<std::decay_t<T>>;
-#if _WIN32
         // https://github.com/blueloveTH/pocketpy/issues/94#issuecomment-1594784476
-        PyObject* obj = new(pool64.alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<T>(val));
-#else
-        PyObject* obj = new(pool64.alloc<__T>()) __T(type, std::forward<T>(val));
-#endif
+        PyObject* obj = new(pool64.alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
         obj->gc.enabled = false;
         _no_gc.push_back(obj);
         return obj;

+ 7 - 7
include/pocketpy/obj.h

@@ -134,8 +134,9 @@ struct Py_ final: PyObject {
             _value._gc_mark();
         }
     }
-    Py_(Type type, const T& value) : PyObject(type), _value(value) {}
-    Py_(Type type, T&& value) : PyObject(type), _value(std::move(value)) {}
+    
+    template <typename... Args>
+    Py_(Type type, Args&&... args) : PyObject(type), _value(std::forward<Args>(args)...) { }
 };
 
 struct MappingProxy{
@@ -320,7 +321,8 @@ struct Py_<Slice> final: PyObject {
 template<>
 struct Py_<Super> final: PyObject {
     Super _value;
-    Py_(Type type, Super val): PyObject(type), _value(val) {}
+    template<typename... Args>
+    Py_(Type type, Args&&... args): PyObject(type), _value(std::forward<Args>(args)...) {}
     void _obj_gc_mark() override {
         PK_OBJ_MARK(_value.first);
     }
@@ -328,8 +330,7 @@ struct Py_<Super> final: PyObject {
 
 template<>
 struct Py_<DummyInstance> final: PyObject {
-    Py_(Type type, DummyInstance val): PyObject(type) {
-        PK_UNUSED(val);
+    Py_(Type type): PyObject(type) {
         enable_instance_dict();
     }
     void _obj_gc_mark() override {}
@@ -346,8 +347,7 @@ struct Py_<Type> final: PyObject {
 
 template<>
 struct Py_<DummyModule> final: PyObject {
-    Py_(Type type, DummyModule val): PyObject(type) {
-        PK_UNUSED(val);
+    Py_(Type type): PyObject(type) {
         enable_instance_dict(kTypeAttrLoadFactor);
     }
     void _obj_gc_mark() override {}

+ 2 - 2
include/pocketpy/vm.h

@@ -42,8 +42,8 @@ namespace pkpy{
         PK_UNUSED(vm);                                                  \
         return PK_OBJ_GET(ctype, obj);                                     \
     }                                                                   \
-    inline PyObject* py_var(VM* vm, const ctype& value) { return vm->heap.gcnew(vm->ptype, value);}     \
-    inline PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew(vm->ptype, std::move(value));}
+    inline PyObject* py_var(VM* vm, const ctype& value) { return vm->heap.gcnew<ctype>(vm->ptype, value);}     \
+    inline PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew<ctype>(vm->ptype, std::move(value));}
 
 
 typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);

+ 1 - 1
src/io.cpp

@@ -99,7 +99,7 @@ void add_module_io(VM* vm){
 void add_module_os(VM* vm){
 #if PK_ENABLE_OS
     PyObject* mod = vm->new_module("os");
-    PyObject* path_obj = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
+    PyObject* path_obj = vm->heap.gcnew<DummyInstance>(vm->tp_object);
     mod->attr().set("path", path_obj);
     
     // Working directory is shared by all VMs!!

+ 4 - 4
src/pocketpy.cpp

@@ -113,7 +113,7 @@ void init_builtins(VM* _vm) {
             vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape());
         }
         Type base = vm->_all_types[type].base;
-        return vm->heap.gcnew(vm->tp_super, Super(args[1], base));
+        return vm->heap.gcnew<Super>(vm->tp_super, args[1], base);
     });
 
     _vm->bind_builtin_func<2>("isinstance", [](VM* vm, ArgsView args) {
@@ -340,7 +340,7 @@ void init_builtins(VM* _vm) {
     _vm->cached_object__new__ = _vm->bind_constructor<1>("object", [](VM* vm, ArgsView args) {
         vm->check_non_tagged_type(args[0], vm->tp_type);
         Type t = PK_OBJ_GET(Type, args[0]);
-        return vm->heap.gcnew<DummyInstance>(t, {});
+        return vm->heap.gcnew<DummyInstance>(t);
     });
 
     _vm->bind_constructor<2>("type", PK_LAMBDA(vm->_t(args[1])));
@@ -1364,8 +1364,8 @@ void add_module_sys(VM* vm){
     vm->setattr(mod, "version", VAR(PK_VERSION));
     vm->setattr(mod, "platform", VAR(PK_SYS_PLATFORM));
 
-    PyObject* stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
-    PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object, {});
+    PyObject* stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
+    PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
     vm->setattr(mod, "stdout", stdout_);
     vm->setattr(mod, "stderr", stderr_);
 

+ 10 - 10
src/vm.cpp

@@ -114,9 +114,9 @@ namespace pkpy{
     }
 
     PyObject* VM::property(NativeFuncC fget, NativeFuncC fset, const char* type_hint){
-        PyObject* _0 = heap.gcnew(tp_native_func, NativeFunc(fget, 1, false));
+        PyObject* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, false);
         PyObject* _1 = vm->None;
-        if(fset != nullptr) _1 = heap.gcnew(tp_native_func, NativeFunc(fset, 2, false));
+        if(fset != nullptr) _1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, false);
         return VAR(Property(_0, _1, type_hint));
     }
 
@@ -434,7 +434,7 @@ PyObject* VM::format(Str spec, PyObject* obj){
 }
 
 PyObject* VM::new_module(StrName name) {
-    PyObject* obj = heap._new<DummyModule>(tp_module, DummyModule());
+    PyObject* obj = heap._new<DummyModule>(tp_module);
     obj->attr().set("__name__", VAR(name.sv()));
     // we do not allow override in order to avoid memory leak
     // it is because Module objects are not garbage collected
@@ -592,12 +592,12 @@ void VM::init_builtin_types(){
     tp_property = _new_type_object("property");
     tp_star_wrapper = _new_type_object("_star_wrapper");
 
-    this->None = heap._new<Dummy>(_new_type_object("NoneType"), {});
-    this->NotImplemented = heap._new<Dummy>(_new_type_object("NotImplementedType"), {});
-    this->Ellipsis = heap._new<Dummy>(_new_type_object("ellipsis"), {});
-    this->True = heap._new<Dummy>(tp_bool, {});
-    this->False = heap._new<Dummy>(tp_bool, {});
-    this->StopIteration = heap._new<Dummy>(_new_type_object("StopIterationType"), {});
+    this->None = heap._new<Dummy>(_new_type_object("NoneType"));
+    this->NotImplemented = heap._new<Dummy>(_new_type_object("NotImplementedType"));
+    this->Ellipsis = heap._new<Dummy>(_new_type_object("ellipsis"));
+    this->True = heap._new<Dummy>(tp_bool);
+    this->False = heap._new<Dummy>(tp_bool);
+    this->StopIteration = heap._new<Dummy>(_new_type_object("StopIterationType"));
 
     this->builtins = new_module("builtins");
     
@@ -804,7 +804,7 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
         if(new_f == cached_object__new__) {
             // fast path for object.__new__
             Type t = PK_OBJ_GET(Type, callable);
-            obj= vm->heap.gcnew<DummyInstance>(t, {});
+            obj= vm->heap.gcnew<DummyInstance>(t);
         }else{
             PUSH(new_f);
             PUSH(PY_NULL);