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

This commit is contained in:
blueloveTH 2023-08-04 22:55:46 +08:00
parent f9d4269caf
commit ed669b4069
8 changed files with 36 additions and 42 deletions

View File

@ -27,7 +27,7 @@ namespace pkpy {
return type; \ 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&); int c99_sizeof(VM*, const Str&);

View File

@ -129,7 +129,7 @@ struct FuncDecl {
}; };
struct UserData{ struct UserData{
char data[16]; char data[15];
bool empty; bool empty;
UserData(): empty(true) {} UserData(): empty(true) {}
@ -186,7 +186,8 @@ struct Function{
template<> template<>
struct Py_<Function> final: PyObject { struct Py_<Function> final: PyObject {
Function _value; 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(); enable_instance_dict();
} }
void _obj_gc_mark() override { void _obj_gc_mark() override {
@ -199,7 +200,8 @@ struct Py_<Function> final: PyObject {
template<> template<>
struct Py_<NativeFunc> final: PyObject { struct Py_<NativeFunc> final: PyObject {
NativeFunc _value; 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(); enable_instance_dict();
} }
void _obj_gc_mark() override { void _obj_gc_mark() override {

View File

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

View File

@ -134,8 +134,9 @@ struct Py_ final: PyObject {
_value._gc_mark(); _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{ struct MappingProxy{
@ -320,7 +321,8 @@ struct Py_<Slice> final: PyObject {
template<> template<>
struct Py_<Super> final: PyObject { struct Py_<Super> final: PyObject {
Super _value; 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 { void _obj_gc_mark() override {
PK_OBJ_MARK(_value.first); PK_OBJ_MARK(_value.first);
} }
@ -328,8 +330,7 @@ struct Py_<Super> final: PyObject {
template<> template<>
struct Py_<DummyInstance> final: PyObject { struct Py_<DummyInstance> final: PyObject {
Py_(Type type, DummyInstance val): PyObject(type) { Py_(Type type): PyObject(type) {
PK_UNUSED(val);
enable_instance_dict(); enable_instance_dict();
} }
void _obj_gc_mark() override {} void _obj_gc_mark() override {}
@ -346,8 +347,7 @@ struct Py_<Type> final: PyObject {
template<> template<>
struct Py_<DummyModule> final: PyObject { struct Py_<DummyModule> final: PyObject {
Py_(Type type, DummyModule val): PyObject(type) { Py_(Type type): PyObject(type) {
PK_UNUSED(val);
enable_instance_dict(kTypeAttrLoadFactor); enable_instance_dict(kTypeAttrLoadFactor);
} }
void _obj_gc_mark() override {} void _obj_gc_mark() override {}

View File

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

View File

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

View File

@ -113,7 +113,7 @@ void init_builtins(VM* _vm) {
vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape()); vm->TypeError("super(): " + _0.escape() + " is not an instance of " + _1.escape());
} }
Type base = vm->_all_types[type].base; 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) { _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->cached_object__new__ = _vm->bind_constructor<1>("object", [](VM* vm, ArgsView args) {
vm->check_non_tagged_type(args[0], vm->tp_type); vm->check_non_tagged_type(args[0], vm->tp_type);
Type t = PK_OBJ_GET(Type, args[0]); 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]))); _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, "version", VAR(PK_VERSION));
vm->setattr(mod, "platform", VAR(PK_SYS_PLATFORM)); vm->setattr(mod, "platform", VAR(PK_SYS_PLATFORM));
PyObject* stdout_ = 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, {}); PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
vm->setattr(mod, "stdout", stdout_); vm->setattr(mod, "stdout", stdout_);
vm->setattr(mod, "stderr", stderr_); vm->setattr(mod, "stderr", stderr_);

View File

@ -114,9 +114,9 @@ namespace pkpy{
} }
PyObject* VM::property(NativeFuncC fget, NativeFuncC fset, const char* type_hint){ 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; 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)); 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* 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())); obj->attr().set("__name__", VAR(name.sv()));
// we do not allow override in order to avoid memory leak // we do not allow override in order to avoid memory leak
// it is because Module objects are not garbage collected // 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_property = _new_type_object("property");
tp_star_wrapper = _new_type_object("_star_wrapper"); tp_star_wrapper = _new_type_object("_star_wrapper");
this->None = heap._new<Dummy>(_new_type_object("NoneType"), {}); this->None = heap._new<Dummy>(_new_type_object("NoneType"));
this->NotImplemented = heap._new<Dummy>(_new_type_object("NotImplementedType"), {}); this->NotImplemented = heap._new<Dummy>(_new_type_object("NotImplementedType"));
this->Ellipsis = heap._new<Dummy>(_new_type_object("ellipsis"), {}); this->Ellipsis = heap._new<Dummy>(_new_type_object("ellipsis"));
this->True = heap._new<Dummy>(tp_bool, {}); this->True = heap._new<Dummy>(tp_bool);
this->False = heap._new<Dummy>(tp_bool, {}); this->False = heap._new<Dummy>(tp_bool);
this->StopIteration = heap._new<Dummy>(_new_type_object("StopIterationType"), {}); this->StopIteration = heap._new<Dummy>(_new_type_object("StopIterationType"));
this->builtins = new_module("builtins"); 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__) { if(new_f == cached_object__new__) {
// fast path for object.__new__ // fast path for object.__new__
Type t = PK_OBJ_GET(Type, callable); Type t = PK_OBJ_GET(Type, callable);
obj= vm->heap.gcnew<DummyInstance>(t, {}); obj= vm->heap.gcnew<DummyInstance>(t);
}else{ }else{
PUSH(new_f); PUSH(new_f);
PUSH(PY_NULL); PUSH(PY_NULL);