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; \
}
#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&);

View File

@ -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 {

View File

@ -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;

View File

@ -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 {}

View File

@ -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*);

View File

@ -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!!

View File

@ -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_);

View File

@ -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);