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{
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<PyLuaFunction>(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<PyLuaTable>(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<PyLuaFunction>(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>(PyLuaTable::_type(vm));
PyObject* obj = vm->new_user_object<PyLuaTable>();
return obj;
}
case LUA_TFUNCTION: {
PyObject* obj = vm->heap.gcnew<PyLuaFunction>(PyLuaFunction::_type(vm));
PyObject* obj = vm->new_user_object<PyLuaFunction>();
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<PyLuaTable>(mod, "Table");
vm->register_user_class<PyLuaFunction>(mod, "Function");
vm->bind(mod, "dostring(__source: str)", [](VM* vm, ArgsView args){
const char* source = CAST(CString, args[0]);

View File

@ -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<wrapped__Point>(vm->builtins);
// use the Point class
vm->exec("a = Point(1, 2)");

View File

@ -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<VoidP>();
```
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){ \
C99Struct& s = CAST(C99Struct&, args[0]); \
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)); \
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<wT>())) return vm->NotImplemented; \
wT& other = _CAST(wT&, _1); \
return VAR(self == other); \
}); \

View File

@ -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<T>(mod, #name, base); \
}
#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{
PY_CLASS(VoidP, c, void_p)
void* ptr;
VoidP(const void* ptr): ptr(const_cast<void*>(ptr)){}

View File

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

View File

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

View File

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

View File

@ -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<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>
Type _find_type_in_cxx_typeid_map(){
auto it = _cxx_typeid_map.find(typeid(T));

View File

@ -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>(Array2d::_type(vm));
PyObject* new_array_obj = vm->new_user_object<Array2d>();
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<Array2d>(_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>(Array2d::_type(vm));
PyObject* new_array_obj = vm->new_user_object<Array2d>();
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>(Array2d::_type(vm));
PyObject* new_array_obj = vm->new_user_object<Array2d>();
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<Array2d>(_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>(Array2d::_type(vm));
PyObject* new_array_obj = vm->new_user_object<Array2d>();
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<Array2d>(mod, "array2d");
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);
});
}

View File

@ -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<VoidP>())) 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<C99Struct>(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<VoidP>(mod, "void_p");
vm->register_user_class<C99Struct>(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<VoidP>())){
vm->ValueError("expected a subclass of void_p");
}
return vm->heap.gcnew<VoidP>(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<VoidP>()); \
mod->attr().set(CNAME "_p", type); \
type_t = PK_OBJ_GET(Type, type); \
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
{
PY_CLASS(PyDequeIter, collections, _deque_iterator)
PyObject *ref;
bool is_reversed;
std::deque<PyObject *>::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<PyObject *> 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>(
PyDequeIter::_type(vm), _0,
self.dequeItems.begin(), self.dequeItems.end());
return vm->new_user_object<PyDequeIter>(_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<PyDeque>(_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>(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<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
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<PyDeque>(mod, "deque");
vm->register_user_class<PyDequeIter>(mod, "_deque_iter");
CodeObject_ code = vm->compile(kPythonLibs_collections, "collections.py", EXEC_MODE);
vm->_exec(code, mod);
}

View File

@ -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<FileIO>(mod, "FileIO");
mod->attr().set("SEEK_SET", VAR(SEEK_SET));
mod->attr().set("SEEK_CUR", VAR(SEEK_CUR));

View File

@ -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<Vec##D>(_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<Mat3x3>(_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<Vec3>(_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<Vec2>(linalg, "vec2");
vm->register_user_class<Vec3>(linalg, "vec3");
vm->register_user_class<Vec4>(linalg, "vec4");
vm->register_user_class<Mat3x3>(linalg, "mat3x3");
PyObject* float_p = vm->_modules["c"]->attr("float_p");
linalg->attr().set("vec2_p", float_p);

View File

@ -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<PyStructTime>(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<LineProfilerW>(mod, "LineProfiler");
}
#else
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) {
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) {
@ -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<RangeIter>(_vm->builtins, "_range_iter");
_vm->register_user_class<ArrayIter>(_vm->builtins, "_array_iter");
_vm->register_user_class<StringIter>(_vm->builtins, "_string_iter");
_vm->register_user_class<Generator>(_vm->builtins, "generator");
_vm->register_user_class<DictItemsIter>(_vm->builtins, "_dict_items_iter");
}
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_PROTECTED(
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{
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>(Random::_type(vm));
vm->register_user_class<Random>(mod, "Random");
PyObject* instance = vm->new_user_object<Random>();
mod->attr().set("seed", vm->getattr(instance, "seed"));
mod->attr().set("random", vm->getattr(instance, "random"));
mod->attr().set("uniform", vm->getattr(instance, "uniform"));