mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
gcnew
constructs PyObject
inplace, no std::move
any more!
This commit is contained in:
parent
f9d4269caf
commit
ed669b4069
@ -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&);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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 {}
|
||||
|
@ -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*);
|
||||
|
@ -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!!
|
||||
|
@ -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_);
|
||||
|
||||
|
20
src/vm.cpp
20
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user