diff --git a/3rd/lua_bridge/src/lua_bridge.cpp b/3rd/lua_bridge/src/lua_bridge.cpp index 2f3c788a..df99f9b2 100644 --- a/3rd/lua_bridge/src/lua_bridge.cpp +++ b/3rd/lua_bridge/src/lua_bridge.cpp @@ -38,8 +38,6 @@ struct PyLuaObject{ }; struct PyLuaTable: PyLuaObject{ - PY_CLASS(PyLuaTable, lua, Table) - static void _register(VM* vm, PyObject* mod, PyObject* type){ Type t = PK_OBJ_GET(Type, type); PyTypeInfo* ti = &vm->_all_types[t]; @@ -198,8 +196,6 @@ static PyObject* lua_popx_multi_to_python(VM* vm, int count){ } struct PyLuaFunction: PyLuaObject{ - PY_CLASS(PyLuaFunction, lua, Function) - static void _register(VM* vm, PyObject* mod, PyObject* type){ vm->bind_notimplemented_constructor(type); vm->_all_types[PK_OBJ_GET(Type, type)].subclass_enabled = false; @@ -274,13 +270,13 @@ void lua_push_from_python(VM* vm, PyObject* val){ } } - if(is_type(val, PyLuaTable::_type(vm))){ + if(vm->is_user_type(val)){ const PyLuaTable& table = _CAST(PyLuaTable&, val); lua_rawgeti(_L, LUA_REGISTRYINDEX, table.r); return; } - if(is_type(val, PyLuaFunction::_type(vm))){ + if(vm->is_user_type(val)){ const PyLuaFunction& func = _CAST(PyLuaFunction&, val); lua_rawgeti(_L, LUA_REGISTRYINDEX, func.r); return; @@ -311,11 +307,11 @@ PyObject* lua_popx_to_python(VM* vm) { return VAR(val); } case LUA_TTABLE: { - PyObject* obj = vm->heap.gcnew(PyLuaTable::_type(vm)); + PyObject* obj = vm->new_user_object(); return obj; } case LUA_TFUNCTION: { - PyObject* obj = vm->heap.gcnew(PyLuaFunction::_type(vm)); + PyObject* obj = vm->new_user_object(); return obj; } default: { @@ -335,8 +331,8 @@ void initialize_lua_bridge(VM* vm, lua_State* newL){ } _L = newL; - PyLuaTable::register_class(vm, mod); - PyLuaFunction::register_class(vm, mod); + vm->register_user_class(mod, "Table"); + vm->register_user_class(mod, "Function"); vm->bind(mod, "dostring(__source: str)", [](VM* vm, ArgsView args){ const char* source = CAST(CString, args[0]); diff --git a/docs/bindings.md b/docs/bindings.md index b68f0958..64acb353 100644 --- a/docs/bindings.md +++ b/docs/bindings.md @@ -169,7 +169,7 @@ struct wrapped__Point{ int main(){ VM* vm = new VM(); // register the wrapper class in builtins - wrapped__Point::register_class(vm, vm->builtins); + vm->register_user_class(vm->builtins); // use the Point class vm->exec("a = Point(1, 2)"); diff --git a/docs/cheatsheet.md b/docs/cheatsheet.md index 610bb5bd..273b8e82 100644 --- a/docs/cheatsheet.md +++ b/docs/cheatsheet.md @@ -141,7 +141,7 @@ Access extended python types ```cpp // VoidP was defined by `PY_CLASS` macro -Type voidp_t = VoidP::_type(vm); +Type voidp_t = vm->_tp_user(); ``` Check if an object is a python type diff --git a/include/pocketpy/bindings.h b/include/pocketpy/bindings.h index a760f007..45099910 100644 --- a/include/pocketpy/bindings.h +++ b/include/pocketpy/bindings.h @@ -142,7 +142,7 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){ vm->bind_func<1>(type, "from_struct", [](VM* vm, ArgsView args){ \ C99Struct& s = CAST(C99Struct&, args[0]); \ if(s.size != sizeof(vT)) vm->ValueError("size mismatch"); \ - PyObject* obj = vm->heap.gcnew(wT::_type(vm)); \ + PyObject* obj = vm->new_user_object(); \ memcpy(_CAST(wT&, obj)._(), s.p, sizeof(vT)); \ return obj; \ }, {}, BindType::STATICMETHOD); \ @@ -163,7 +163,7 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){ }); \ vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \ wT& self = _CAST(wT&, _0); \ - if(!vm->isinstance(_1, wT::_type(vm))) return vm->NotImplemented; \ + if(!vm->isinstance(_1, vm->_tp_user())) return vm->NotImplemented; \ wT& other = _CAST(wT&, _1); \ return VAR(self == other); \ }); \ diff --git a/include/pocketpy/cffi.h b/include/pocketpy/cffi.h index 9d9893db..f39809e0 100644 --- a/include/pocketpy/cffi.h +++ b/include/pocketpy/cffi.h @@ -6,22 +6,14 @@ namespace pkpy { #define PY_CLASS(T, mod, name) \ - static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \ - static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \ - std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \ - if(mod_name != #mod) throw std::runtime_error(_S("register_class() failed: ", mod_name, " != ", #mod).str()); \ - PyObject* type = vm->new_type_object(mod, #name, base); \ - mod->attr().set(#name, type); \ - vm->_cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type); \ - T::_register(vm, mod, type); \ - return type; \ + [[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \ + [[deprecated]] static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \ + return vm->register_user_class(mod, #name, base); \ } -#define VAR_T(T, ...) vm->heap.gcnew(T::_type(vm), __VA_ARGS__) +#define VAR_T(T, ...) vm->heap.gcnew(vm->_tp_user(), __VA_ARGS__) struct VoidP{ - PY_CLASS(VoidP, c, void_p) - void* ptr; VoidP(const void* ptr): ptr(const_cast(ptr)){} diff --git a/include/pocketpy/common.h b/include/pocketpy/common.h index 5d2431f2..7d1421a1 100644 --- a/include/pocketpy/common.h +++ b/include/pocketpy/common.h @@ -20,7 +20,7 @@ #include #include -#define PK_VERSION "1.4.6" +#define PK_VERSION "1.5.0" #include "config.h" #include "export.h" diff --git a/include/pocketpy/iter.h b/include/pocketpy/iter.h index 2e3635bc..ed143844 100644 --- a/include/pocketpy/iter.h +++ b/include/pocketpy/iter.h @@ -7,7 +7,6 @@ namespace pkpy{ struct RangeIter{ - PY_CLASS(RangeIter, builtins, _range_iterator) Range r; i64 current; RangeIter(Range r) : r(r), current(r.start) {} @@ -16,7 +15,6 @@ struct RangeIter{ }; struct ArrayIter{ - PY_CLASS(ArrayIter, builtins, _array_iterator) PyObject* ref; PyObject** begin; PyObject** end; @@ -30,7 +28,6 @@ struct ArrayIter{ }; struct StringIter{ - PY_CLASS(StringIter, builtins, _string_iterator) PyObject* ref; int i; // byte index StringIter(PyObject* ref) : ref(ref), i(0) {} @@ -39,7 +36,6 @@ struct StringIter{ }; struct Generator{ - PY_CLASS(Generator, builtins, generator) Frame frame; int state; // 0,1,2 List s_backup; @@ -58,7 +54,6 @@ struct Generator{ }; struct DictItemsIter{ - PY_CLASS(DictItemsIter, builtins, _dict_items_iterator) PyObject* ref; int i; DictItemsIter(PyObject* ref) : ref(ref) { diff --git a/include/pocketpy/linalg.h b/include/pocketpy/linalg.h index 7b400fca..55df1586 100644 --- a/include/pocketpy/linalg.h +++ b/include/pocketpy/linalg.h @@ -7,8 +7,6 @@ namespace pkpy{ inline bool isclose(float a, float b){ return std::fabs(a - b) < 1e-4; } struct Vec2{ - PY_CLASS(Vec2, linalg, vec2) - Vec2* _() { return this; } static void _register(VM* vm, PyObject* mod, PyObject* type); @@ -35,8 +33,6 @@ struct Vec2{ }; struct Vec3{ - PY_CLASS(Vec3, linalg, vec3) - Vec3* _() { return this; } static void _register(VM* vm, PyObject* mod, PyObject* type); @@ -62,8 +58,6 @@ struct Vec3{ }; struct Vec4{ - PY_CLASS(Vec4, linalg, vec4) - Vec4* _() { return this; } static void _register(VM* vm, PyObject* mod, PyObject* type); @@ -88,8 +82,6 @@ struct Vec4{ }; struct Mat3x3{ - PY_CLASS(Mat3x3, linalg, mat3x3) - Mat3x3* _(){ return this; } static void _register(VM* vm, PyObject* mod, PyObject* type); diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 2f96f763..f59dbf57 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -425,6 +425,30 @@ public: PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT); PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr); + template + PyObject* register_user_class(PyObject* mod, StrName name, Type base=0, bool subclass_enabled=false){ + PyObject* type = new_type_object(mod, name, base, subclass_enabled); + mod->attr().set(name, type); + _cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type); + T::_register(vm, mod, type); + return type; + } + + template + PyObject* new_user_object(Args&&... args){ + return heap.gcnew(_tp_user(), std::forward(args)...); + } + + template + Type _tp_user(){ + return _find_type_in_cxx_typeid_map(); + } + + template + bool is_user_type(PyObject* obj){ + return _tp(obj) == _tp_user(); + } + template Type _find_type_in_cxx_typeid_map(){ auto it = _cxx_typeid_map.find(typeid(T)); diff --git a/src/array2d.cpp b/src/array2d.cpp index 437aaf78..9440aeb9 100644 --- a/src/array2d.cpp +++ b/src/array2d.cpp @@ -4,7 +4,6 @@ namespace pkpy{ struct Array2d{ PK_ALWAYS_PASS_BY_POINTER(Array2d) - PY_CLASS(Array2d, array2d, array2d) PyObject** data; int n_cols; @@ -105,7 +104,7 @@ struct Array2d{ if(is_type(xy[0], VM::tp_slice) && is_type(xy[1], VM::tp_slice)){ HANDLE_SLICE(); - PyObject* new_array_obj = vm->heap.gcnew(Array2d::_type(vm)); + PyObject* new_array_obj = vm->new_user_object(); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); new_array.init(stop_col - start_col, stop_row - start_row); for(int j = start_row; j < stop_row; j++){ @@ -150,7 +149,7 @@ struct Array2d{ return; } - if(!is_type(_2, Array2d::_type(vm))){ + if(!vm->is_user_type(_2)){ vm->TypeError(_S("expected int/float/str/bool/None or an array2d instance")); } @@ -192,7 +191,7 @@ struct Array2d{ vm->bind(type, "map(self, f)", [](VM* vm, ArgsView args){ Array2d& self = PK_OBJ_GET(Array2d, args[0]); PyObject* f = args[1]; - PyObject* new_array_obj = vm->heap.gcnew(Array2d::_type(vm)); + PyObject* new_array_obj = vm->new_user_object(); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); new_array.init(self.n_cols, self.n_rows); for(int i = 0; i < new_array.numel; i++){ @@ -203,7 +202,7 @@ struct Array2d{ vm->bind(type, "copy(self)", [](VM* vm, ArgsView args){ Array2d& self = PK_OBJ_GET(Array2d, args[0]); - PyObject* new_array_obj = vm->heap.gcnew(Array2d::_type(vm)); + PyObject* new_array_obj = vm->new_user_object(); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); new_array.init(self.n_cols, self.n_rows); for(int i = 0; i < new_array.numel; i++){ @@ -255,7 +254,7 @@ struct Array2d{ vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ Array2d& self = PK_OBJ_GET(Array2d, _0); - if(!is_type(_1, Array2d::_type(vm))) return vm->NotImplemented; + if(!vm->is_user_type(_1)) return vm->NotImplemented; Array2d& other = PK_OBJ_GET(Array2d, _1); if(self.n_cols != other.n_cols || self.n_rows != other.n_rows) return vm->False; for(int i = 0; i < self.numel; i++){ @@ -266,7 +265,7 @@ struct Array2d{ vm->bind(type, "count_neighbors(self, value, neighborhood='Moore') -> array2d[int]", [](VM* vm, ArgsView args){ Array2d& self = PK_OBJ_GET(Array2d, args[0]); - PyObject* new_array_obj = vm->heap.gcnew(Array2d::_type(vm)); + PyObject* new_array_obj = vm->new_user_object(); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); new_array.init(self.n_cols, self.n_rows); PyObject* value = args[1]; @@ -347,8 +346,7 @@ struct Array2d{ struct Array2dIter{ PK_ALWAYS_PASS_BY_POINTER(Array2dIter) - PY_CLASS(Array2dIter, array2d, _array2d_iterator) - + PyObject* ref; int i; Array2dIter(PyObject* ref) : ref(ref), i(0) {} @@ -375,10 +373,10 @@ struct Array2dIter{ void add_module_array2d(VM* vm){ PyObject* mod = vm->new_module("array2d"); - Array2d::register_class(vm, mod); - Array2dIter::register_class(vm, mod); + vm->register_user_class(mod, "array2d"); + vm->register_user_class(mod, "_array2d_iter"); - vm->bind__iter__(Array2d::_type(vm), [](VM* vm, PyObject* _0){ + vm->bind__iter__(vm->_tp_user(), [](VM* vm, PyObject* _0){ return VAR_T(Array2dIter, _0); }); } diff --git a/src/cffi.cpp b/src/cffi.cpp index 21156abf..2f6c9f88 100644 --- a/src/cffi.cpp +++ b/src/cffi.cpp @@ -21,7 +21,7 @@ namespace pkpy{ #define BIND_CMP(name, op) \ vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ \ - if(!vm->isinstance(rhs, VoidP::_type(vm))) return vm->NotImplemented; \ + if(!vm->isinstance(rhs, vm->_tp_user())) return vm->NotImplemented; \ void* _0 = PK_OBJ_GET(VoidP, lhs).ptr; \ void* _1 = PK_OBJ_GET(VoidP, rhs).ptr; \ return VAR(_0 op _1); \ @@ -96,7 +96,7 @@ namespace pkpy{ vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ C99Struct& self = _CAST(C99Struct&, lhs); - if(!is_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented; + if(!vm->is_user_type(rhs)) return vm->NotImplemented; C99Struct& other = _CAST(C99Struct&, rhs); bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0; return VAR(ok); @@ -161,15 +161,16 @@ void add_module_c(VM* vm){ return vm->None; }); - VoidP::register_class(vm, mod); - C99Struct::register_class(vm, mod); + vm->register_user_class(mod, "void_p"); + vm->register_user_class(mod, "struct"); + mod->attr().set("NULL", VAR_T(VoidP, nullptr)); vm->bind(mod, "p_cast(ptr: 'void_p', cls: type[T]) -> T", [](VM* vm, ArgsView args){ VoidP& ptr = CAST(VoidP&, args[0]); vm->check_type(args[1], vm->tp_type); Type cls = PK_OBJ_GET(Type, args[1]); - if(!vm->issubclass(cls, VoidP::_type(vm))){ + if(!vm->issubclass(cls, vm->_tp_user())){ vm->ValueError("expected a subclass of void_p"); } return vm->heap.gcnew(cls, ptr.ptr); @@ -194,7 +195,7 @@ void add_module_c(VM* vm){ T val = CAST(T, args[0]); \ return VAR_T(C99Struct, &val, sizeof(T)); \ }); \ - type = vm->new_type_object(mod, CNAME "_p", VoidP::_type(vm)); \ + type = vm->new_type_object(mod, CNAME "_p", vm->_tp_user()); \ mod->attr().set(CNAME "_p", type); \ type_t = PK_OBJ_GET(Type, type); \ vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){ \ diff --git a/src/collections.cpp b/src/collections.cpp index b3a8cd80..fe365734 100644 --- a/src/collections.cpp +++ b/src/collections.cpp @@ -4,7 +4,6 @@ namespace pkpy { struct PyDequeIter // Iterator for the deque type { - PY_CLASS(PyDequeIter, collections, _deque_iterator) PyObject *ref; bool is_reversed; std::deque::iterator begin, end, current; @@ -48,7 +47,6 @@ namespace pkpy } struct PyDeque { - PY_CLASS(PyDeque, collections, deque); PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen); // constructor // PyDeque members std::deque dequeItems; @@ -108,9 +106,7 @@ namespace pkpy vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0) { PyDeque &self = _CAST(PyDeque &, _0); - return vm->heap.gcnew( - PyDequeIter::_type(vm), _0, - self.dequeItems.begin(), self.dequeItems.end()); + return vm->new_user_object(_0, self.dequeItems.begin(), self.dequeItems.end()); }); vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0) @@ -134,7 +130,7 @@ namespace pkpy vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1) { const PyDeque &self = _CAST(PyDeque&, _0); - if(!is_type(_0, PyDeque::_type(vm))) return vm->NotImplemented; + if(!vm->is_user_type(_0)) return vm->NotImplemented; const PyDeque &other = _CAST(PyDeque&, _1); if (self.dequeItems.size() != other.dequeItems.size()) return vm->False; for (int i = 0; i < self.dequeItems.size(); i++){ @@ -214,8 +210,8 @@ namespace pkpy { auto _lock = vm->heap.gc_scope_lock(); // locking the heap PyDeque &self = _CAST(PyDeque &, args[0]); - PyObject *newDequeObj = vm->heap.gcnew(PyDeque::_type(vm), vm, vm->None, vm->None); // create the empty deque - PyDeque &newDeque = _CAST(PyDeque &, newDequeObj); // cast it to PyDeque so we can use its methods + PyObject *newDequeObj = vm->new_user_object(vm, vm->None, vm->None); // create the empty deque + PyDeque &newDeque = _CAST(PyDeque &, newDequeObj); // cast it to PyDeque so we can use its methods for (auto it = self.dequeItems.begin(); it != self.dequeItems.end(); ++it) newDeque.insertObj(false, true, -1, *it); return newDequeObj; @@ -546,12 +542,11 @@ namespace pkpy PK_OBJ_MARK(obj); } /// @brief registers the PyDeque class - /// @param vm is needed for the new_module and register_class void add_module_collections(VM *vm) { PyObject *mod = vm->new_module("collections"); - PyDeque::register_class(vm, mod); - PyDequeIter::register_class(vm, mod); + vm->register_user_class(mod, "deque"); + vm->register_user_class(mod, "_deque_iter"); CodeObject_ code = vm->compile(kPythonLibs_collections, "collections.py", EXEC_MODE); vm->_exec(code, mod); } diff --git a/src/io.cpp b/src/io.cpp index 069686cc..76d2061c 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -10,8 +10,6 @@ namespace pkpy{ #if PK_ENABLE_OS struct FileIO { - PY_CLASS(FileIO, io, FileIO) - FILE* fp; bool is_text; @@ -142,7 +140,7 @@ void FileIO::close(){ void add_module_io(VM* vm){ PyObject* mod = vm->new_module("io"); - FileIO::register_class(vm, mod); + vm->register_user_class(mod, "FileIO"); mod->attr().set("SEEK_SET", VAR(SEEK_SET)); mod->attr().set("SEEK_CUR", VAR(SEEK_CUR)); diff --git a/src/linalg.cpp b/src/linalg.cpp index bc9d4233..8a6602b3 100644 --- a/src/linalg.cpp +++ b/src/linalg.cpp @@ -24,15 +24,15 @@ namespace pkpy{ #define BIND_VEC_FUNCTION_1(D, name) \ vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \ - Vec##D& self = _CAST(Vec##D&, args[0]); \ - Vec##D& other = CAST(Vec##D&, args[1]); \ + Vec##D& self = _CAST(Vec##D&, args[0]); \ + Vec##D& other = CAST(Vec##D&, args[1]); \ return VAR(self.name(other)); \ }); -#define BIND_VEC_MUL_OP(D) \ +#define BIND_VEC_MUL_OP(D) \ vm->bind__mul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \ Vec##D& self = _CAST(Vec##D&, _0); \ - if(is_type(_1, Vec##D::_type(vm))){ \ + if(vm->is_user_type(_1)){ \ Vec##D& other = _CAST(Vec##D&, _1); \ return VAR(self * other); \ } \ @@ -369,11 +369,11 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s vm->bind__matmul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ Mat3x3& self = _CAST(Mat3x3&, _0); - if(is_type(_1, Mat3x3::_type(vm))){ + if(vm->is_user_type(_1)){ const Mat3x3& other = _CAST(Mat3x3&, _1); return VAR_T(Mat3x3, self.matmul(other)); } - if(is_type(_1, Vec3::_type(vm))){ + if(vm->is_user_type(_1)){ const Vec3& other = _CAST(Vec3&, _1); return VAR_T(Vec3, self.matmul(other)); } @@ -540,10 +540,11 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s void add_module_linalg(VM* vm){ PyObject* linalg = vm->new_module("linalg"); - Vec2::register_class(vm, linalg); - Vec3::register_class(vm, linalg); - Vec4::register_class(vm, linalg); - Mat3x3::register_class(vm, linalg); + + vm->register_user_class(linalg, "vec2"); + vm->register_user_class(linalg, "vec3"); + vm->register_user_class(linalg, "vec4"); + vm->register_user_class(linalg, "mat3x3"); PyObject* float_p = vm->_modules["c"]->attr("float_p"); linalg->attr().set("vec2_p", float_p); diff --git a/src/modules.cpp b/src/modules.cpp index d329c1ab..78f59d77 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -13,8 +13,6 @@ void add_module_operator(VM* vm){ } struct PyStructTime{ - PY_CLASS(PyStructTime, time, struct_time) - int tm_year; int tm_mon; int tm_mday; @@ -56,7 +54,7 @@ struct PyStructTime{ void add_module_time(VM* vm){ PyObject* mod = vm->new_module("time"); - PyStructTime::register_class(vm, mod); + vm->register_user_class(mod, "struct_time"); vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) { auto now = std::chrono::system_clock::now(); @@ -298,8 +296,6 @@ struct _LpGuard{ // line_profiler wrapper struct LineProfilerW{ - PY_CLASS(LineProfilerW, line_profiler, LineProfiler) - LineProfiler profiler; static void _register(VM* vm, PyObject* mod, PyObject* type){ @@ -352,7 +348,7 @@ _LpGuard::~_LpGuard(){ void add_module_line_profiler(VM *vm){ PyObject* mod = vm->new_module("line_profiler"); - LineProfilerW::register_class(vm, mod); + vm->register_user_class(mod, "LineProfiler"); } #else void add_module_line_profiler(VM* vm){ diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index 08c50f0c..b3b4e9dd 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -1383,7 +1383,7 @@ void init_builtins(VM* _vm) { }); _vm->bind_method<0>(VM::tp_dict, "items", [](VM* vm, ArgsView args) { - return vm->heap.gcnew(DictItemsIter::_type(vm), args[0]); + return vm->new_user_object(args[0]); }); _vm->bind_method<1>(VM::tp_dict, "update", [](VM* vm, ArgsView args) { @@ -1495,11 +1495,11 @@ void init_builtins(VM* _vm) { return VAR(self.msg); }); - RangeIter::register_class(_vm, _vm->builtins); - ArrayIter::register_class(_vm, _vm->builtins); - StringIter::register_class(_vm, _vm->builtins); - Generator::register_class(_vm, _vm->builtins); - DictItemsIter::register_class(_vm, _vm->builtins); + _vm->register_user_class(_vm->builtins, "_range_iter"); + _vm->register_user_class(_vm->builtins, "_array_iter"); + _vm->register_user_class(_vm->builtins, "_string_iter"); + _vm->register_user_class(_vm->builtins, "generator"); + _vm->register_user_class(_vm->builtins, "_dict_items_iter"); } void VM::post_init(){ diff --git a/src/pocketpy_c.cpp b/src/pocketpy_c.cpp index 47ce89ae..f0222ce3 100644 --- a/src/pocketpy_c.cpp +++ b/src/pocketpy_c.cpp @@ -277,7 +277,7 @@ bool pkpy_is_voidp(pkpy_vm* vm_handle, int i){ PK_ASSERT_NO_ERROR() PK_PROTECTED( PyObject* item = stack_item(vm, i); - return is_type(item, VoidP::_type(vm)); + return vm->is_user_type(item); ) } diff --git a/src/random.cpp b/src/random.cpp index c001824f..8407586a 100644 --- a/src/random.cpp +++ b/src/random.cpp @@ -126,7 +126,6 @@ struct mt19937{ namespace pkpy{ struct Random{ - PY_CLASS(Random, random, Random) mt19937 gen; Random(){ @@ -215,8 +214,8 @@ struct Random{ void add_module_random(VM* vm){ PyObject* mod = vm->new_module("random"); - Random::register_class(vm, mod); - PyObject* instance = vm->heap.gcnew(Random::_type(vm)); + vm->register_user_class(mod, "Random"); + PyObject* instance = vm->new_user_object(); mod->attr().set("seed", vm->getattr(instance, "seed")); mod->attr().set("random", vm->getattr(instance, "random")); mod->attr().set("uniform", vm->getattr(instance, "uniform"));