diff --git a/include/pocketpy/cffi.h b/include/pocketpy/cffi.h index da76a9d8..f28583ec 100644 --- a/include/pocketpy/cffi.h +++ b/include/pocketpy/cffi.h @@ -27,7 +27,7 @@ namespace pkpy { return type; \ } -#define VAR_T(T, ...) vm->heap.gcnew(T::_type(vm), T(__VA_ARGS__)) +#define VAR_T(T, ...) vm->heap.gcnew(T::_type(vm), __VA_ARGS__) int c99_sizeof(VM*, const Str&); diff --git a/include/pocketpy/codeobject.h b/include/pocketpy/codeobject.h index 9d1dd11c..5422a58b 100644 --- a/include/pocketpy/codeobject.h +++ b/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_ final: PyObject { Function _value; - Py_(Type type, Function val): PyObject(type), _value(val) { + template + Py_(Type type, Args&&... args): PyObject(type), _value(std::forward(args)...) { enable_instance_dict(); } void _obj_gc_mark() override { @@ -199,7 +200,8 @@ struct Py_ final: PyObject { template<> struct Py_ final: PyObject { NativeFunc _value; - Py_(Type type, NativeFunc val): PyObject(type), _value(val) { + template + Py_(Type type, Args&&... args): PyObject(type), _value(std::forward(args)...) { enable_instance_dict(); } void _obj_gc_mark() override { diff --git a/include/pocketpy/gc.h b/include/pocketpy/gc.h index bb50662e..ad79f8ca 100644 --- a/include/pocketpy/gc.h +++ b/include/pocketpy/gc.h @@ -37,29 +37,21 @@ struct ManagedHeap{ } /********************/ - template - PyObject* gcnew(Type type, T&& val){ + template + PyObject* gcnew(Type type, Args&&... args){ using __T = Py_>; -#if _WIN32 // https://github.com/blueloveTH/pocketpy/issues/94#issuecomment-1594784476 - PyObject* obj = new(pool64.alloc<__T>()) Py_>(type, std::forward(val)); -#else - PyObject* obj = new(pool64.alloc<__T>()) __T(type, std::forward(val)); -#endif + PyObject* obj = new(pool64.alloc<__T>()) Py_>(type, std::forward(args)...); gen.push_back(obj); gc_counter++; return obj; } - template - PyObject* _new(Type type, T&& val){ + template + PyObject* _new(Type type, Args&&... args){ using __T = Py_>; -#if _WIN32 // https://github.com/blueloveTH/pocketpy/issues/94#issuecomment-1594784476 - PyObject* obj = new(pool64.alloc<__T>()) Py_>(type, std::forward(val)); -#else - PyObject* obj = new(pool64.alloc<__T>()) __T(type, std::forward(val)); -#endif + PyObject* obj = new(pool64.alloc<__T>()) Py_>(type, std::forward(args)...); obj->gc.enabled = false; _no_gc.push_back(obj); return obj; diff --git a/include/pocketpy/obj.h b/include/pocketpy/obj.h index 12cdf9a7..c3f00da7 100644 --- a/include/pocketpy/obj.h +++ b/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 + Py_(Type type, Args&&... args) : PyObject(type), _value(std::forward(args)...) { } }; struct MappingProxy{ @@ -320,7 +321,8 @@ struct Py_ final: PyObject { template<> struct Py_ final: PyObject { Super _value; - Py_(Type type, Super val): PyObject(type), _value(val) {} + template + Py_(Type type, Args&&... args): PyObject(type), _value(std::forward(args)...) {} void _obj_gc_mark() override { PK_OBJ_MARK(_value.first); } @@ -328,8 +330,7 @@ struct Py_ final: PyObject { template<> struct Py_ 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_ final: PyObject { template<> struct Py_ 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 {} diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index adde17e3..b786a440 100644 --- a/include/pocketpy/vm.h +++ b/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(vm->ptype, value);} \ + inline PyObject* py_var(VM* vm, ctype&& value) { return vm->heap.gcnew(vm->ptype, std::move(value));} typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*); diff --git a/src/io.cpp b/src/io.cpp index e02f8d43..9b2a59d7 100644 --- a/src/io.cpp +++ b/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(vm->tp_object, {}); + PyObject* path_obj = vm->heap.gcnew(vm->tp_object); mod->attr().set("path", path_obj); // Working directory is shared by all VMs!! diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index b198118f..e65b457c 100644 --- a/src/pocketpy.cpp +++ b/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(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(t, {}); + return vm->heap.gcnew(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(vm->tp_object, {}); - PyObject* stderr_ = vm->heap.gcnew(vm->tp_object, {}); + PyObject* stdout_ = vm->heap.gcnew(vm->tp_object); + PyObject* stderr_ = vm->heap.gcnew(vm->tp_object); vm->setattr(mod, "stdout", stdout_); vm->setattr(mod, "stderr", stderr_); diff --git a/src/vm.cpp b/src/vm.cpp index 8381dc1a..21b3860c 100644 --- a/src/vm.cpp +++ b/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(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(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(tp_module, DummyModule()); + PyObject* obj = heap._new(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(_new_type_object("NoneType"), {}); - this->NotImplemented = heap._new(_new_type_object("NotImplementedType"), {}); - this->Ellipsis = heap._new(_new_type_object("ellipsis"), {}); - this->True = heap._new(tp_bool, {}); - this->False = heap._new(tp_bool, {}); - this->StopIteration = heap._new(_new_type_object("StopIterationType"), {}); + this->None = heap._new(_new_type_object("NoneType")); + this->NotImplemented = heap._new(_new_type_object("NotImplementedType")); + this->Ellipsis = heap._new(_new_type_object("ellipsis")); + this->True = heap._new(tp_bool); + this->False = heap._new(tp_bool); + this->StopIteration = heap._new(_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(t, {}); + obj= vm->heap.gcnew(t); }else{ PUSH(new_f); PUSH(PY_NULL);