remove PY_CLASS macro

This commit is contained in:
blueloveTH 2024-05-02 15:55:22 +08:00
parent 43ec97a707
commit f944113567
18 changed files with 85 additions and 98 deletions

View File

@ -38,8 +38,6 @@ struct PyLuaObject{
}; };
struct PyLuaTable: PyLuaObject{ struct PyLuaTable: PyLuaObject{
PY_CLASS(PyLuaTable, lua, Table)
static void _register(VM* vm, PyObject* mod, PyObject* type){ static void _register(VM* vm, PyObject* mod, PyObject* type){
Type t = PK_OBJ_GET(Type, type); Type t = PK_OBJ_GET(Type, type);
PyTypeInfo* ti = &vm->_all_types[t]; PyTypeInfo* ti = &vm->_all_types[t];
@ -198,8 +196,6 @@ static PyObject* lua_popx_multi_to_python(VM* vm, int count){
} }
struct PyLuaFunction: PyLuaObject{ struct PyLuaFunction: PyLuaObject{
PY_CLASS(PyLuaFunction, lua, Function)
static void _register(VM* vm, PyObject* mod, PyObject* type){ static void _register(VM* vm, PyObject* mod, PyObject* type){
vm->bind_notimplemented_constructor<PyLuaFunction>(type); vm->bind_notimplemented_constructor<PyLuaFunction>(type);
vm->_all_types[PK_OBJ_GET(Type, type)].subclass_enabled = false; 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<PyLuaTable>(val)){
const PyLuaTable& table = _CAST(PyLuaTable&, val); const PyLuaTable& table = _CAST(PyLuaTable&, val);
lua_rawgeti(_L, LUA_REGISTRYINDEX, table.r); lua_rawgeti(_L, LUA_REGISTRYINDEX, table.r);
return; return;
} }
if(is_type(val, PyLuaFunction::_type(vm))){ if(vm->is_user_type<PyLuaFunction>(val)){
const PyLuaFunction& func = _CAST(PyLuaFunction&, val); const PyLuaFunction& func = _CAST(PyLuaFunction&, val);
lua_rawgeti(_L, LUA_REGISTRYINDEX, func.r); lua_rawgeti(_L, LUA_REGISTRYINDEX, func.r);
return; return;
@ -311,11 +307,11 @@ PyObject* lua_popx_to_python(VM* vm) {
return VAR(val); return VAR(val);
} }
case LUA_TTABLE: { case LUA_TTABLE: {
PyObject* obj = vm->heap.gcnew<PyLuaTable>(PyLuaTable::_type(vm)); PyObject* obj = vm->new_user_object<PyLuaTable>();
return obj; return obj;
} }
case LUA_TFUNCTION: { case LUA_TFUNCTION: {
PyObject* obj = vm->heap.gcnew<PyLuaFunction>(PyLuaFunction::_type(vm)); PyObject* obj = vm->new_user_object<PyLuaFunction>();
return obj; return obj;
} }
default: { default: {
@ -335,8 +331,8 @@ void initialize_lua_bridge(VM* vm, lua_State* newL){
} }
_L = newL; _L = newL;
PyLuaTable::register_class(vm, mod); vm->register_user_class<PyLuaTable>(mod, "Table");
PyLuaFunction::register_class(vm, mod); vm->register_user_class<PyLuaFunction>(mod, "Function");
vm->bind(mod, "dostring(__source: str)", [](VM* vm, ArgsView args){ vm->bind(mod, "dostring(__source: str)", [](VM* vm, ArgsView args){
const char* source = CAST(CString, args[0]); const char* source = CAST(CString, args[0]);

View File

@ -169,7 +169,7 @@ struct wrapped__Point{
int main(){ int main(){
VM* vm = new VM(); VM* vm = new VM();
// register the wrapper class in builtins // register the wrapper class in builtins
wrapped__Point::register_class(vm, vm->builtins); vm->register_user_class<wrapped__Point>(vm->builtins);
// use the Point class // use the Point class
vm->exec("a = Point(1, 2)"); vm->exec("a = Point(1, 2)");

View File

@ -141,7 +141,7 @@ Access extended python types
```cpp ```cpp
// VoidP was defined by `PY_CLASS` macro // VoidP was defined by `PY_CLASS` macro
Type voidp_t = VoidP::_type(vm); Type voidp_t = vm->_tp_user<VoidP>();
``` ```
Check if an object is a python type Check if an object is a python type

View File

@ -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){ \ vm->bind_func<1>(type, "from_struct", [](VM* vm, ArgsView args){ \
C99Struct& s = CAST(C99Struct&, args[0]); \ C99Struct& s = CAST(C99Struct&, args[0]); \
if(s.size != sizeof(vT)) vm->ValueError("size mismatch"); \ if(s.size != sizeof(vT)) vm->ValueError("size mismatch"); \
PyObject* obj = vm->heap.gcnew<wT>(wT::_type(vm)); \ PyObject* obj = vm->new_user_object<wT>(); \
memcpy(_CAST(wT&, obj)._(), s.p, sizeof(vT)); \ memcpy(_CAST(wT&, obj)._(), s.p, sizeof(vT)); \
return obj; \ return obj; \
}, {}, BindType::STATICMETHOD); \ }, {}, 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){ \ vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
wT& self = _CAST(wT&, _0); \ wT& self = _CAST(wT&, _0); \
if(!vm->isinstance(_1, wT::_type(vm))) return vm->NotImplemented; \ if(!vm->isinstance(_1, vm->_tp_user<wT>())) return vm->NotImplemented; \
wT& other = _CAST(wT&, _1); \ wT& other = _CAST(wT&, _1); \
return VAR(self == other); \ return VAR(self == other); \
}); \ }); \

View File

@ -6,22 +6,14 @@
namespace pkpy { namespace pkpy {
#define PY_CLASS(T, mod, name) \ #define PY_CLASS(T, mod, name) \
static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \ [[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \
static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \ [[deprecated]] static PyObject* register_class(VM* vm, PyObject* mod, Type base=0) { \
std::string_view mod_name = PK_OBJ_GET(Str, mod->attr("__name__")).sv(); \ return vm->register_user_class<T>(mod, #name, base); \
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; \
} }
#define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), __VA_ARGS__) #define VAR_T(T, ...) vm->heap.gcnew<T>(vm->_tp_user<T>(), __VA_ARGS__)
struct VoidP{ struct VoidP{
PY_CLASS(VoidP, c, void_p)
void* ptr; void* ptr;
VoidP(const void* ptr): ptr(const_cast<void*>(ptr)){} VoidP(const void* ptr): ptr(const_cast<void*>(ptr)){}

View File

@ -20,7 +20,7 @@
#include <typeindex> #include <typeindex>
#include <initializer_list> #include <initializer_list>
#define PK_VERSION "1.4.6" #define PK_VERSION "1.5.0"
#include "config.h" #include "config.h"
#include "export.h" #include "export.h"

View File

@ -7,7 +7,6 @@
namespace pkpy{ namespace pkpy{
struct RangeIter{ struct RangeIter{
PY_CLASS(RangeIter, builtins, _range_iterator)
Range r; Range r;
i64 current; i64 current;
RangeIter(Range r) : r(r), current(r.start) {} RangeIter(Range r) : r(r), current(r.start) {}
@ -16,7 +15,6 @@ struct RangeIter{
}; };
struct ArrayIter{ struct ArrayIter{
PY_CLASS(ArrayIter, builtins, _array_iterator)
PyObject* ref; PyObject* ref;
PyObject** begin; PyObject** begin;
PyObject** end; PyObject** end;
@ -30,7 +28,6 @@ struct ArrayIter{
}; };
struct StringIter{ struct StringIter{
PY_CLASS(StringIter, builtins, _string_iterator)
PyObject* ref; PyObject* ref;
int i; // byte index int i; // byte index
StringIter(PyObject* ref) : ref(ref), i(0) {} StringIter(PyObject* ref) : ref(ref), i(0) {}
@ -39,7 +36,6 @@ struct StringIter{
}; };
struct Generator{ struct Generator{
PY_CLASS(Generator, builtins, generator)
Frame frame; Frame frame;
int state; // 0,1,2 int state; // 0,1,2
List s_backup; List s_backup;
@ -58,7 +54,6 @@ struct Generator{
}; };
struct DictItemsIter{ struct DictItemsIter{
PY_CLASS(DictItemsIter, builtins, _dict_items_iterator)
PyObject* ref; PyObject* ref;
int i; int i;
DictItemsIter(PyObject* ref) : ref(ref) { DictItemsIter(PyObject* ref) : ref(ref) {

View File

@ -7,8 +7,6 @@ namespace pkpy{
inline bool isclose(float a, float b){ return std::fabs(a - b) < 1e-4; } inline bool isclose(float a, float b){ return std::fabs(a - b) < 1e-4; }
struct Vec2{ struct Vec2{
PY_CLASS(Vec2, linalg, vec2)
Vec2* _() { return this; } Vec2* _() { return this; }
static void _register(VM* vm, PyObject* mod, PyObject* type); static void _register(VM* vm, PyObject* mod, PyObject* type);
@ -35,8 +33,6 @@ struct Vec2{
}; };
struct Vec3{ struct Vec3{
PY_CLASS(Vec3, linalg, vec3)
Vec3* _() { return this; } Vec3* _() { return this; }
static void _register(VM* vm, PyObject* mod, PyObject* type); static void _register(VM* vm, PyObject* mod, PyObject* type);
@ -62,8 +58,6 @@ struct Vec3{
}; };
struct Vec4{ struct Vec4{
PY_CLASS(Vec4, linalg, vec4)
Vec4* _() { return this; } Vec4* _() { return this; }
static void _register(VM* vm, PyObject* mod, PyObject* type); static void _register(VM* vm, PyObject* mod, PyObject* type);
@ -88,8 +82,6 @@ struct Vec4{
}; };
struct Mat3x3{ struct Mat3x3{
PY_CLASS(Mat3x3, linalg, mat3x3)
Mat3x3* _(){ return this; } Mat3x3* _(){ return this; }
static void _register(VM* vm, PyObject* mod, PyObject* type); static void _register(VM* vm, PyObject* mod, PyObject* type);

View File

@ -425,6 +425,30 @@ public:
PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT); PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr); PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
template<typename T>
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<typename T, typename ...Args>
PyObject* new_user_object(Args&&... args){
return heap.gcnew<T>(_tp_user<T>(), std::forward<Args>(args)...);
}
template<typename T>
Type _tp_user(){
return _find_type_in_cxx_typeid_map<T>();
}
template<typename T>
bool is_user_type(PyObject* obj){
return _tp(obj) == _tp_user<T>();
}
template<typename T> template<typename T>
Type _find_type_in_cxx_typeid_map(){ Type _find_type_in_cxx_typeid_map(){
auto it = _cxx_typeid_map.find(typeid(T)); auto it = _cxx_typeid_map.find(typeid(T));

View File

@ -4,7 +4,6 @@ namespace pkpy{
struct Array2d{ struct Array2d{
PK_ALWAYS_PASS_BY_POINTER(Array2d) PK_ALWAYS_PASS_BY_POINTER(Array2d)
PY_CLASS(Array2d, array2d, array2d)
PyObject** data; PyObject** data;
int n_cols; int n_cols;
@ -105,7 +104,7 @@ struct Array2d{
if(is_type(xy[0], VM::tp_slice) && is_type(xy[1], VM::tp_slice)){ if(is_type(xy[0], VM::tp_slice) && is_type(xy[1], VM::tp_slice)){
HANDLE_SLICE(); HANDLE_SLICE();
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm)); PyObject* new_array_obj = vm->new_user_object<Array2d>();
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
new_array.init(stop_col - start_col, stop_row - start_row); new_array.init(stop_col - start_col, stop_row - start_row);
for(int j = start_row; j < stop_row; j++){ for(int j = start_row; j < stop_row; j++){
@ -150,7 +149,7 @@ struct Array2d{
return; return;
} }
if(!is_type(_2, Array2d::_type(vm))){ if(!vm->is_user_type<Array2d>(_2)){
vm->TypeError(_S("expected int/float/str/bool/None or an array2d instance")); 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){ vm->bind(type, "map(self, f)", [](VM* vm, ArgsView args){
Array2d& self = PK_OBJ_GET(Array2d, args[0]); Array2d& self = PK_OBJ_GET(Array2d, args[0]);
PyObject* f = args[1]; PyObject* f = args[1];
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm)); PyObject* new_array_obj = vm->new_user_object<Array2d>();
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
new_array.init(self.n_cols, self.n_rows); new_array.init(self.n_cols, self.n_rows);
for(int i = 0; i < new_array.numel; i++){ for(int i = 0; i < new_array.numel; i++){
@ -203,7 +202,7 @@ struct Array2d{
vm->bind(type, "copy(self)", [](VM* vm, ArgsView args){ vm->bind(type, "copy(self)", [](VM* vm, ArgsView args){
Array2d& self = PK_OBJ_GET(Array2d, args[0]); Array2d& self = PK_OBJ_GET(Array2d, args[0]);
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm)); PyObject* new_array_obj = vm->new_user_object<Array2d>();
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
new_array.init(self.n_cols, self.n_rows); new_array.init(self.n_cols, self.n_rows);
for(int i = 0; i < new_array.numel; i++){ 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){ vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
Array2d& self = PK_OBJ_GET(Array2d, _0); Array2d& self = PK_OBJ_GET(Array2d, _0);
if(!is_type(_1, Array2d::_type(vm))) return vm->NotImplemented; if(!vm->is_user_type<Array2d>(_1)) return vm->NotImplemented;
Array2d& other = PK_OBJ_GET(Array2d, _1); Array2d& other = PK_OBJ_GET(Array2d, _1);
if(self.n_cols != other.n_cols || self.n_rows != other.n_rows) return vm->False; if(self.n_cols != other.n_cols || self.n_rows != other.n_rows) return vm->False;
for(int i = 0; i < self.numel; i++){ 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){ vm->bind(type, "count_neighbors(self, value, neighborhood='Moore') -> array2d[int]", [](VM* vm, ArgsView args){
Array2d& self = PK_OBJ_GET(Array2d, args[0]); Array2d& self = PK_OBJ_GET(Array2d, args[0]);
PyObject* new_array_obj = vm->heap.gcnew<Array2d>(Array2d::_type(vm)); PyObject* new_array_obj = vm->new_user_object<Array2d>();
Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj); Array2d& new_array = PK_OBJ_GET(Array2d, new_array_obj);
new_array.init(self.n_cols, self.n_rows); new_array.init(self.n_cols, self.n_rows);
PyObject* value = args[1]; PyObject* value = args[1];
@ -347,8 +346,7 @@ struct Array2d{
struct Array2dIter{ struct Array2dIter{
PK_ALWAYS_PASS_BY_POINTER(Array2dIter) PK_ALWAYS_PASS_BY_POINTER(Array2dIter)
PY_CLASS(Array2dIter, array2d, _array2d_iterator)
PyObject* ref; PyObject* ref;
int i; int i;
Array2dIter(PyObject* ref) : ref(ref), i(0) {} Array2dIter(PyObject* ref) : ref(ref), i(0) {}
@ -375,10 +373,10 @@ struct Array2dIter{
void add_module_array2d(VM* vm){ void add_module_array2d(VM* vm){
PyObject* mod = vm->new_module("array2d"); PyObject* mod = vm->new_module("array2d");
Array2d::register_class(vm, mod); vm->register_user_class<Array2d>(mod, "array2d");
Array2dIter::register_class(vm, mod); vm->register_user_class<Array2dIter>(mod, "_array2d_iter");
vm->bind__iter__(Array2d::_type(vm), [](VM* vm, PyObject* _0){ vm->bind__iter__(vm->_tp_user<Array2d>(), [](VM* vm, PyObject* _0){
return VAR_T(Array2dIter, _0); return VAR_T(Array2dIter, _0);
}); });
} }

View File

@ -21,7 +21,7 @@ namespace pkpy{
#define BIND_CMP(name, op) \ #define BIND_CMP(name, op) \
vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){ \ 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<VoidP>())) return vm->NotImplemented; \
void* _0 = PK_OBJ_GET(VoidP, lhs).ptr; \ void* _0 = PK_OBJ_GET(VoidP, lhs).ptr; \
void* _1 = PK_OBJ_GET(VoidP, rhs).ptr; \ void* _1 = PK_OBJ_GET(VoidP, rhs).ptr; \
return VAR(_0 op _1); \ 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){ vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
C99Struct& self = _CAST(C99Struct&, lhs); C99Struct& self = _CAST(C99Struct&, lhs);
if(!is_type(rhs, C99Struct::_type(vm))) return vm->NotImplemented; if(!vm->is_user_type<C99Struct>(rhs)) return vm->NotImplemented;
C99Struct& other = _CAST(C99Struct&, rhs); C99Struct& other = _CAST(C99Struct&, rhs);
bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0; bool ok = self.size == other.size && memcmp(self.p, other.p, self.size) == 0;
return VAR(ok); return VAR(ok);
@ -161,15 +161,16 @@ void add_module_c(VM* vm){
return vm->None; return vm->None;
}); });
VoidP::register_class(vm, mod); vm->register_user_class<VoidP>(mod, "void_p");
C99Struct::register_class(vm, mod); vm->register_user_class<C99Struct>(mod, "struct");
mod->attr().set("NULL", VAR_T(VoidP, nullptr)); mod->attr().set("NULL", VAR_T(VoidP, nullptr));
vm->bind(mod, "p_cast(ptr: 'void_p', cls: type[T]) -> T", [](VM* vm, ArgsView args){ vm->bind(mod, "p_cast(ptr: 'void_p', cls: type[T]) -> T", [](VM* vm, ArgsView args){
VoidP& ptr = CAST(VoidP&, args[0]); VoidP& ptr = CAST(VoidP&, args[0]);
vm->check_type(args[1], vm->tp_type); vm->check_type(args[1], vm->tp_type);
Type cls = PK_OBJ_GET(Type, args[1]); Type cls = PK_OBJ_GET(Type, args[1]);
if(!vm->issubclass(cls, VoidP::_type(vm))){ if(!vm->issubclass(cls, vm->_tp_user<VoidP>())){
vm->ValueError("expected a subclass of void_p"); vm->ValueError("expected a subclass of void_p");
} }
return vm->heap.gcnew<VoidP>(cls, ptr.ptr); return vm->heap.gcnew<VoidP>(cls, ptr.ptr);
@ -194,7 +195,7 @@ void add_module_c(VM* vm){
T val = CAST(T, args[0]); \ T val = CAST(T, args[0]); \
return VAR_T(C99Struct, &val, sizeof(T)); \ 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<VoidP>()); \
mod->attr().set(CNAME "_p", type); \ mod->attr().set(CNAME "_p", type); \
type_t = PK_OBJ_GET(Type, type); \ type_t = PK_OBJ_GET(Type, type); \
vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){ \ vm->bind_method<0>(type, "read", [](VM* vm, ArgsView args){ \

View File

@ -4,7 +4,6 @@ namespace pkpy
{ {
struct PyDequeIter // Iterator for the deque type struct PyDequeIter // Iterator for the deque type
{ {
PY_CLASS(PyDequeIter, collections, _deque_iterator)
PyObject *ref; PyObject *ref;
bool is_reversed; bool is_reversed;
std::deque<PyObject *>::iterator begin, end, current; std::deque<PyObject *>::iterator begin, end, current;
@ -48,7 +47,6 @@ namespace pkpy
} }
struct PyDeque struct PyDeque
{ {
PY_CLASS(PyDeque, collections, deque);
PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen); // constructor PyDeque(VM *vm, PyObject *iterable, PyObject *maxlen); // constructor
// PyDeque members // PyDeque members
std::deque<PyObject *> dequeItems; std::deque<PyObject *> dequeItems;
@ -108,9 +106,7 @@ namespace pkpy
vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0) vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0)
{ {
PyDeque &self = _CAST(PyDeque &, _0); PyDeque &self = _CAST(PyDeque &, _0);
return vm->heap.gcnew<PyDequeIter>( return vm->new_user_object<PyDequeIter>(_0, self.dequeItems.begin(), self.dequeItems.end());
PyDequeIter::_type(vm), _0,
self.dequeItems.begin(), self.dequeItems.end());
}); });
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0) 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) vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1)
{ {
const PyDeque &self = _CAST(PyDeque&, _0); const PyDeque &self = _CAST(PyDeque&, _0);
if(!is_type(_0, PyDeque::_type(vm))) return vm->NotImplemented; if(!vm->is_user_type<PyDeque>(_0)) return vm->NotImplemented;
const PyDeque &other = _CAST(PyDeque&, _1); const PyDeque &other = _CAST(PyDeque&, _1);
if (self.dequeItems.size() != other.dequeItems.size()) return vm->False; if (self.dequeItems.size() != other.dequeItems.size()) return vm->False;
for (int i = 0; i < self.dequeItems.size(); i++){ 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 auto _lock = vm->heap.gc_scope_lock(); // locking the heap
PyDeque &self = _CAST(PyDeque &, args[0]); PyDeque &self = _CAST(PyDeque &, args[0]);
PyObject *newDequeObj = vm->heap.gcnew<PyDeque>(PyDeque::_type(vm), vm, vm->None, vm->None); // create the empty deque PyObject *newDequeObj = vm->new_user_object<PyDeque>(vm, vm->None, vm->None); // create the empty deque
PyDeque &newDeque = _CAST(PyDeque &, newDequeObj); // cast it to PyDeque so we can use its methods 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) for (auto it = self.dequeItems.begin(); it != self.dequeItems.end(); ++it)
newDeque.insertObj(false, true, -1, *it); newDeque.insertObj(false, true, -1, *it);
return newDequeObj; return newDequeObj;
@ -546,12 +542,11 @@ namespace pkpy
PK_OBJ_MARK(obj); PK_OBJ_MARK(obj);
} }
/// @brief registers the PyDeque class /// @brief registers the PyDeque class
/// @param vm is needed for the new_module and register_class
void add_module_collections(VM *vm) void add_module_collections(VM *vm)
{ {
PyObject *mod = vm->new_module("collections"); PyObject *mod = vm->new_module("collections");
PyDeque::register_class(vm, mod); vm->register_user_class<PyDeque>(mod, "deque");
PyDequeIter::register_class(vm, mod); vm->register_user_class<PyDequeIter>(mod, "_deque_iter");
CodeObject_ code = vm->compile(kPythonLibs_collections, "collections.py", EXEC_MODE); CodeObject_ code = vm->compile(kPythonLibs_collections, "collections.py", EXEC_MODE);
vm->_exec(code, mod); vm->_exec(code, mod);
} }

View File

@ -10,8 +10,6 @@ namespace pkpy{
#if PK_ENABLE_OS #if PK_ENABLE_OS
struct FileIO { struct FileIO {
PY_CLASS(FileIO, io, FileIO)
FILE* fp; FILE* fp;
bool is_text; bool is_text;
@ -142,7 +140,7 @@ void FileIO::close(){
void add_module_io(VM* vm){ void add_module_io(VM* vm){
PyObject* mod = vm->new_module("io"); PyObject* mod = vm->new_module("io");
FileIO::register_class(vm, mod); vm->register_user_class<FileIO>(mod, "FileIO");
mod->attr().set("SEEK_SET", VAR(SEEK_SET)); mod->attr().set("SEEK_SET", VAR(SEEK_SET));
mod->attr().set("SEEK_CUR", VAR(SEEK_CUR)); mod->attr().set("SEEK_CUR", VAR(SEEK_CUR));

View File

@ -24,15 +24,15 @@ namespace pkpy{
#define BIND_VEC_FUNCTION_1(D, name) \ #define BIND_VEC_FUNCTION_1(D, name) \
vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \ vm->bind_method<1>(type, #name, [](VM* vm, ArgsView args){ \
Vec##D& self = _CAST(Vec##D&, args[0]); \ Vec##D& self = _CAST(Vec##D&, args[0]); \
Vec##D& other = CAST(Vec##D&, args[1]); \ Vec##D& other = CAST(Vec##D&, args[1]); \
return VAR(self.name(other)); \ 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){ \ vm->bind__mul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
Vec##D& self = _CAST(Vec##D&, _0); \ Vec##D& self = _CAST(Vec##D&, _0); \
if(is_type(_1, Vec##D::_type(vm))){ \ if(vm->is_user_type<Vec##D>(_1)){ \
Vec##D& other = _CAST(Vec##D&, _1); \ Vec##D& other = _CAST(Vec##D&, _1); \
return VAR(self * other); \ 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){ vm->bind__matmul__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
Mat3x3& self = _CAST(Mat3x3&, _0); Mat3x3& self = _CAST(Mat3x3&, _0);
if(is_type(_1, Mat3x3::_type(vm))){ if(vm->is_user_type<Mat3x3>(_1)){
const Mat3x3& other = _CAST(Mat3x3&, _1); const Mat3x3& other = _CAST(Mat3x3&, _1);
return VAR_T(Mat3x3, self.matmul(other)); return VAR_T(Mat3x3, self.matmul(other));
} }
if(is_type(_1, Vec3::_type(vm))){ if(vm->is_user_type<Vec3>(_1)){
const Vec3& other = _CAST(Vec3&, _1); const Vec3& other = _CAST(Vec3&, _1);
return VAR_T(Vec3, self.matmul(other)); 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){ void add_module_linalg(VM* vm){
PyObject* linalg = vm->new_module("linalg"); PyObject* linalg = vm->new_module("linalg");
Vec2::register_class(vm, linalg);
Vec3::register_class(vm, linalg); vm->register_user_class<Vec2>(linalg, "vec2");
Vec4::register_class(vm, linalg); vm->register_user_class<Vec3>(linalg, "vec3");
Mat3x3::register_class(vm, linalg); vm->register_user_class<Vec4>(linalg, "vec4");
vm->register_user_class<Mat3x3>(linalg, "mat3x3");
PyObject* float_p = vm->_modules["c"]->attr("float_p"); PyObject* float_p = vm->_modules["c"]->attr("float_p");
linalg->attr().set("vec2_p", float_p); linalg->attr().set("vec2_p", float_p);

View File

@ -13,8 +13,6 @@ void add_module_operator(VM* vm){
} }
struct PyStructTime{ struct PyStructTime{
PY_CLASS(PyStructTime, time, struct_time)
int tm_year; int tm_year;
int tm_mon; int tm_mon;
int tm_mday; int tm_mday;
@ -56,7 +54,7 @@ struct PyStructTime{
void add_module_time(VM* vm){ void add_module_time(VM* vm){
PyObject* mod = vm->new_module("time"); PyObject* mod = vm->new_module("time");
PyStructTime::register_class(vm, mod); vm->register_user_class<PyStructTime>(mod, "struct_time");
vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) { vm->bind_func<0>(mod, "time", [](VM* vm, ArgsView args) {
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
@ -298,8 +296,6 @@ struct _LpGuard{
// line_profiler wrapper // line_profiler wrapper
struct LineProfilerW{ struct LineProfilerW{
PY_CLASS(LineProfilerW, line_profiler, LineProfiler)
LineProfiler profiler; LineProfiler profiler;
static void _register(VM* vm, PyObject* mod, PyObject* type){ static void _register(VM* vm, PyObject* mod, PyObject* type){
@ -352,7 +348,7 @@ _LpGuard::~_LpGuard(){
void add_module_line_profiler(VM *vm){ void add_module_line_profiler(VM *vm){
PyObject* mod = vm->new_module("line_profiler"); PyObject* mod = vm->new_module("line_profiler");
LineProfilerW::register_class(vm, mod); vm->register_user_class<LineProfilerW>(mod, "LineProfiler");
} }
#else #else
void add_module_line_profiler(VM* vm){ void add_module_line_profiler(VM* vm){

View File

@ -1383,7 +1383,7 @@ void init_builtins(VM* _vm) {
}); });
_vm->bind_method<0>(VM::tp_dict, "items", [](VM* vm, ArgsView args) { _vm->bind_method<0>(VM::tp_dict, "items", [](VM* vm, ArgsView args) {
return vm->heap.gcnew<DictItemsIter>(DictItemsIter::_type(vm), args[0]); return vm->new_user_object<DictItemsIter>(args[0]);
}); });
_vm->bind_method<1>(VM::tp_dict, "update", [](VM* vm, ArgsView args) { _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); return VAR(self.msg);
}); });
RangeIter::register_class(_vm, _vm->builtins); _vm->register_user_class<RangeIter>(_vm->builtins, "_range_iter");
ArrayIter::register_class(_vm, _vm->builtins); _vm->register_user_class<ArrayIter>(_vm->builtins, "_array_iter");
StringIter::register_class(_vm, _vm->builtins); _vm->register_user_class<StringIter>(_vm->builtins, "_string_iter");
Generator::register_class(_vm, _vm->builtins); _vm->register_user_class<Generator>(_vm->builtins, "generator");
DictItemsIter::register_class(_vm, _vm->builtins); _vm->register_user_class<DictItemsIter>(_vm->builtins, "_dict_items_iter");
} }
void VM::post_init(){ void VM::post_init(){

View File

@ -277,7 +277,7 @@ bool pkpy_is_voidp(pkpy_vm* vm_handle, int i){
PK_ASSERT_NO_ERROR() PK_ASSERT_NO_ERROR()
PK_PROTECTED( PK_PROTECTED(
PyObject* item = stack_item(vm, i); PyObject* item = stack_item(vm, i);
return is_type(item, VoidP::_type(vm)); return vm->is_user_type<VoidP>(item);
) )
} }

View File

@ -126,7 +126,6 @@ struct mt19937{
namespace pkpy{ namespace pkpy{
struct Random{ struct Random{
PY_CLASS(Random, random, Random)
mt19937 gen; mt19937 gen;
Random(){ Random(){
@ -215,8 +214,8 @@ struct Random{
void add_module_random(VM* vm){ void add_module_random(VM* vm){
PyObject* mod = vm->new_module("random"); PyObject* mod = vm->new_module("random");
Random::register_class(vm, mod); vm->register_user_class<Random>(mod, "Random");
PyObject* instance = vm->heap.gcnew<Random>(Random::_type(vm)); PyObject* instance = vm->new_user_object<Random>();
mod->attr().set("seed", vm->getattr(instance, "seed")); mod->attr().set("seed", vm->getattr(instance, "seed"));
mod->attr().set("random", vm->getattr(instance, "random")); mod->attr().set("random", vm->getattr(instance, "random"));
mod->attr().set("uniform", vm->getattr(instance, "uniform")); mod->attr().set("uniform", vm->getattr(instance, "uniform"));