remove VAR_T

This commit is contained in:
blueloveTH 2024-05-02 16:24:13 +08:00
parent 84c4bf590c
commit dcb970d327
8 changed files with 37 additions and 39 deletions

View File

@ -148,15 +148,15 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
}, {}, BindType::STATICMETHOD); \ }, {}, BindType::STATICMETHOD); \
vm->bind_method<0>(type, "to_struct", [](VM* vm, ArgsView args){ \ vm->bind_method<0>(type, "to_struct", [](VM* vm, ArgsView args){ \
wT& self = _CAST(wT&, args[0]); \ wT& self = _CAST(wT&, args[0]); \
return VAR_T(C99Struct, self._(), sizeof(vT)); \ return vm->new_user_object<C99Struct>(self._(), sizeof(vT)); \
}); \ }); \
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){ \ vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){ \
wT& self = _CAST(wT&, args[0]); \ wT& self = _CAST(wT&, args[0]); \
return VAR_T(VoidP, self._()); \ return vm->new_user_object<VoidP>(self._()); \
}); \ }); \
vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){ \ vm->bind_method<0>(type, "copy", [](VM* vm, ArgsView args){ \
wT& self = _CAST(wT&, args[0]); \ wT& self = _CAST(wT&, args[0]); \
return VAR_T(wT, *self._()); \ return vm->new_user_object<wT>(*self._()); \
}); \ }); \
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){ \ vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){ \
return VAR(sizeof(vT)); \ return VAR(sizeof(vT)); \

View File

@ -11,8 +11,6 @@ namespace pkpy {
return vm->register_user_class<T>(mod, #name, base); \ return vm->register_user_class<T>(mod, #name, base); \
} }
#define VAR_T(T, ...) vm->heap.gcnew<T>(vm->_tp_user<T>(), __VA_ARGS__)
struct VoidP{ struct VoidP{
void* ptr; void* ptr;
VoidP(const void* ptr): ptr(const_cast<void*>(ptr)){} VoidP(const void* ptr): ptr(const_cast<void*>(ptr)){}

View File

@ -377,7 +377,7 @@ void add_module_array2d(VM* vm){
vm->register_user_class<Array2dIter>(mod, "_array2d_iter"); vm->register_user_class<Array2dIter>(mod, "_array2d_iter");
vm->bind__iter__(vm->_tp_user<Array2d>(), [](VM* vm, PyObject* _0){ vm->bind__iter__(vm->_tp_user<Array2d>(), [](VM* vm, PyObject* _0){
return VAR_T(Array2dIter, _0); return vm->new_user_object<Array2dIter>(_0);
}); });
} }

View File

@ -69,7 +69,7 @@ namespace pkpy{
else vm->ValueError(_S("invalid hex char: '", s[i+1], "'")); else vm->ValueError(_S("invalid hex char: '", s[i+1], "'"));
buffer.p[i/2] = c; buffer.p[i/2] = c;
} }
return VAR_T(C99Struct, std::move(buffer)); return vm->new_user_object<C99Struct>(std::move(buffer));
}, {}, BindType::STATICMETHOD); }, {}, BindType::STATICMETHOD);
vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
@ -81,7 +81,7 @@ namespace pkpy{
vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "addr", [](VM* vm, ArgsView args){
C99Struct& self = _CAST(C99Struct&, args[0]); C99Struct& self = _CAST(C99Struct&, args[0]);
return VAR_T(VoidP, self.p); return vm->new_user_object<VoidP>(self.p);
}); });
vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "sizeof", [](VM* vm, ArgsView args){
@ -164,7 +164,7 @@ void add_module_c(VM* vm){
vm->register_user_class<VoidP>(mod, "void_p", true); vm->register_user_class<VoidP>(mod, "void_p", true);
vm->register_user_class<C99Struct>(mod, "struct", true); vm->register_user_class<C99Struct>(mod, "struct", true);
mod->attr().set("NULL", VAR_T(VoidP, nullptr)); mod->attr().set("NULL", vm->new_user_object<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]);
@ -193,7 +193,7 @@ void add_module_c(VM* vm){
#define BIND_PRIMITIVE(T, CNAME) \ #define BIND_PRIMITIVE(T, CNAME) \
vm->bind_func<1>(mod, CNAME "_", [](VM* vm, ArgsView args){ \ vm->bind_func<1>(mod, CNAME "_", [](VM* vm, ArgsView args){ \
T val = CAST(T, args[0]); \ T val = CAST(T, args[0]); \
return VAR_T(C99Struct, &val, sizeof(T)); \ return vm->new_user_object<C99Struct>(&val, sizeof(T)); \
}); \ }); \
type = vm->new_type_object(mod, CNAME "_p", vm->_tp_user<VoidP>()); \ type = vm->new_type_object(mod, CNAME "_p", vm->_tp_user<VoidP>()); \
mod->attr().set(CNAME "_p", type); \ mod->attr().set(CNAME "_p", type); \
@ -273,7 +273,7 @@ void add_module_c(VM* vm){
} }
PyObject* from_void_p(VM* vm, void* p){ PyObject* from_void_p(VM* vm, void* p){
return VAR_T(VoidP, p); return vm->new_user_object<VoidP>(p);
} }
} // namespace pkpy } // namespace pkpy

View File

@ -110,7 +110,7 @@ namespace pkpy{
} }
PyObject* VM::_py_generator(Frame&& frame, ArgsView buffer){ PyObject* VM::_py_generator(Frame&& frame, ArgsView buffer){
return VAR_T(Generator, std::move(frame), buffer); return vm->new_user_object<Generator>(std::move(frame), buffer);
} }
} // namespace pkpy } // namespace pkpy

View File

@ -157,7 +157,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
vm->bind_method<1>(type, "rotate", [](VM* vm, ArgsView args){ vm->bind_method<1>(type, "rotate", [](VM* vm, ArgsView args){
Vec2 self = _CAST(Vec2&, args[0]); Vec2 self = _CAST(Vec2&, args[0]);
float radian = CAST(f64, args[1]); float radian = CAST(f64, args[1]);
return VAR_T(Vec2, self.rotate(radian)); return vm->new_user_object<Vec2>(self.rotate(radian));
}); });
vm->bind_method<1>(type, "rotate_", [](VM* vm, ArgsView args){ vm->bind_method<1>(type, "rotate_", [](VM* vm, ArgsView args){
@ -340,42 +340,42 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
vm->bind__add__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ vm->bind__add__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
Mat3x3& self = _CAST(Mat3x3&, _0); Mat3x3& self = _CAST(Mat3x3&, _0);
Mat3x3& other = CAST(Mat3x3&, _1); Mat3x3& other = CAST(Mat3x3&, _1);
return VAR_T(Mat3x3, self + other); return vm->new_user_object<Mat3x3>(self + other);
}); });
vm->bind__sub__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ vm->bind__sub__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
Mat3x3& self = _CAST(Mat3x3&, _0); Mat3x3& self = _CAST(Mat3x3&, _0);
Mat3x3& other = CAST(Mat3x3&, _1); Mat3x3& other = CAST(Mat3x3&, _1);
return VAR_T(Mat3x3, self - other); return vm->new_user_object<Mat3x3>(self - other);
}); });
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){
Mat3x3& self = _CAST(Mat3x3&, _0); Mat3x3& self = _CAST(Mat3x3&, _0);
f64 other = CAST_F(_1); f64 other = CAST_F(_1);
return VAR_T(Mat3x3, self * other); return vm->new_user_object<Mat3x3>(self * other);
}); });
vm->bind_method<1>(type, "__rmul__", [](VM* vm, ArgsView args){ vm->bind_method<1>(type, "__rmul__", [](VM* vm, ArgsView args){
Mat3x3& self = _CAST(Mat3x3&, args[0]); Mat3x3& self = _CAST(Mat3x3&, args[0]);
f64 other = CAST_F(args[1]); f64 other = CAST_F(args[1]);
return VAR_T(Mat3x3, self * other); return vm->new_user_object<Mat3x3>(self * other);
}); });
vm->bind__truediv__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ vm->bind__truediv__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
Mat3x3& self = _CAST(Mat3x3&, _0); Mat3x3& self = _CAST(Mat3x3&, _0);
f64 other = CAST_F(_1); f64 other = CAST_F(_1);
return VAR_T(Mat3x3, self / other); return vm->new_user_object<Mat3x3>(self / other);
}); });
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(vm->is_user_type<Mat3x3>(_1)){ 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 vm->new_user_object<Mat3x3>(self.matmul(other));
} }
if(vm->is_user_type<Vec3>(_1)){ 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 vm->new_user_object<Vec3>(self.matmul(other));
} }
return vm->NotImplemented; return vm->NotImplemented;
}); });
@ -384,7 +384,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
const Mat3x3& self = _CAST(Mat3x3&, args[0]); const Mat3x3& self = _CAST(Mat3x3&, args[0]);
const Mat3x3& other = CAST(Mat3x3&, args[1]); const Mat3x3& other = CAST(Mat3x3&, args[1]);
if(args[2] == vm->None){ if(args[2] == vm->None){
return VAR_T(Mat3x3, self.matmul(other)); return vm->new_user_object<Mat3x3>(self.matmul(other));
}else{ }else{
Mat3x3& out = CAST(Mat3x3&, args[2]); Mat3x3& out = CAST(Mat3x3&, args[2]);
out = self.matmul(other); out = self.matmul(other);
@ -399,21 +399,21 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
vm->bind_method<0>(type, "transpose", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "transpose", [](VM* vm, ArgsView args){
Mat3x3& self = _CAST(Mat3x3&, args[0]); Mat3x3& self = _CAST(Mat3x3&, args[0]);
return VAR_T(Mat3x3, self.transpose()); return vm->new_user_object<Mat3x3>(self.transpose());
}); });
vm->bind__invert__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){ vm->bind__invert__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
Mat3x3& self = _CAST(Mat3x3&, obj); Mat3x3& self = _CAST(Mat3x3&, obj);
Mat3x3 ret; Mat3x3 ret;
if(!self.inverse(ret)) vm->ValueError("matrix is not invertible"); if(!self.inverse(ret)) vm->ValueError("matrix is not invertible");
return VAR_T(Mat3x3, ret); return vm->new_user_object<Mat3x3>(ret);
}); });
vm->bind_method<0>(type, "inverse", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "inverse", [](VM* vm, ArgsView args){
Mat3x3& self = _CAST(Mat3x3&, args[0]); Mat3x3& self = _CAST(Mat3x3&, args[0]);
Mat3x3 ret; Mat3x3 ret;
if(!self.inverse(ret)) vm->ValueError("matrix is not invertible"); if(!self.inverse(ret)) vm->ValueError("matrix is not invertible");
return VAR_T(Mat3x3, ret); return vm->new_user_object<Mat3x3>(ret);
}); });
vm->bind_method<0>(type, "inverse_", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "inverse_", [](VM* vm, ArgsView args){
@ -432,17 +432,17 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
// @staticmethod // @staticmethod
vm->bind(type, "zeros()", [](VM* vm, ArgsView args){ vm->bind(type, "zeros()", [](VM* vm, ArgsView args){
return VAR_T(Mat3x3, Mat3x3::zeros()); return vm->new_user_object<Mat3x3>(Mat3x3::zeros());
}, {}, BindType::STATICMETHOD); }, {}, BindType::STATICMETHOD);
// @staticmethod // @staticmethod
vm->bind(type, "ones()", [](VM* vm, ArgsView args){ vm->bind(type, "ones()", [](VM* vm, ArgsView args){
return VAR_T(Mat3x3, Mat3x3::ones()); return vm->new_user_object<Mat3x3>(Mat3x3::ones());
}, {}, BindType::STATICMETHOD); }, {}, BindType::STATICMETHOD);
// @staticmethod // @staticmethod
vm->bind(type, "identity()", [](VM* vm, ArgsView args){ vm->bind(type, "identity()", [](VM* vm, ArgsView args){
return VAR_T(Mat3x3, Mat3x3::identity()); return vm->new_user_object<Mat3x3>(Mat3x3::identity());
}, {}, BindType::STATICMETHOD); }, {}, BindType::STATICMETHOD);
/*************** affine transformations ***************/ /*************** affine transformations ***************/
@ -451,7 +451,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
Vec2 t = CAST(Vec2, args[0]); Vec2 t = CAST(Vec2, args[0]);
f64 r = CAST_F(args[1]); f64 r = CAST_F(args[1]);
Vec2 s = CAST(Vec2, args[2]); Vec2 s = CAST(Vec2, args[2]);
return VAR_T(Mat3x3, Mat3x3::trs(t, r, s)); return vm->new_user_object<Mat3x3>(Mat3x3::trs(t, r, s));
}, {}, BindType::STATICMETHOD); }, {}, BindType::STATICMETHOD);
vm->bind(type, "copy_trs_(self, t: vec2, r: float, s: vec2)", [](VM* vm, ArgsView args){ vm->bind(type, "copy_trs_(self, t: vec2, r: float, s: vec2)", [](VM* vm, ArgsView args){
@ -491,7 +491,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
vm->bind_method<0>(type, "_t", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "_t", [](VM* vm, ArgsView args){
Mat3x3& self = _CAST(Mat3x3&, args[0]); Mat3x3& self = _CAST(Mat3x3&, args[0]);
return VAR_T(Vec2, self._t()); return vm->new_user_object<Vec2>(self._t());
}); });
vm->bind_method<0>(type, "_r", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "_r", [](VM* vm, ArgsView args){
@ -501,14 +501,14 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
vm->bind_method<0>(type, "_s", [](VM* vm, ArgsView args){ vm->bind_method<0>(type, "_s", [](VM* vm, ArgsView args){
Mat3x3& self = _CAST(Mat3x3&, args[0]); Mat3x3& self = _CAST(Mat3x3&, args[0]);
return VAR_T(Vec2, self._s()); return vm->new_user_object<Vec2>(self._s());
}); });
vm->bind_method<1>(type, "transform_point", [](VM* vm, ArgsView args){ vm->bind_method<1>(type, "transform_point", [](VM* vm, ArgsView args){
const Mat3x3& self = _CAST(Mat3x3&, args[0]); const Mat3x3& self = _CAST(Mat3x3&, args[0]);
Vec2 v = CAST(Vec2, args[1]); Vec2 v = CAST(Vec2, args[1]);
Vec2 res(self._11 * v.x + self._12 * v.y + self._13, self._21 * v.x + self._22 * v.y + self._23); Vec2 res(self._11 * v.x + self._12 * v.y + self._13, self._21 * v.x + self._22 * v.y + self._23);
return VAR_T(Vec2, res); return vm->new_user_object<Vec2>(res);
}); });
vm->bind_method<1>(type, "inverse_transform_point", [](VM* vm, ArgsView args){ vm->bind_method<1>(type, "inverse_transform_point", [](VM* vm, ArgsView args){
@ -517,14 +517,14 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
Mat3x3 inv; Mat3x3 inv;
if(!self.inverse(inv)) vm->ValueError("matrix is not invertible"); if(!self.inverse(inv)) vm->ValueError("matrix is not invertible");
Vec2 res(inv._11 * v.x + inv._12 * v.y + inv._13, inv._21 * v.x + inv._22 * v.y + inv._23); Vec2 res(inv._11 * v.x + inv._12 * v.y + inv._13, inv._21 * v.x + inv._22 * v.y + inv._23);
return VAR_T(Vec2, res); return vm->new_user_object<Vec2>(res);
}); });
vm->bind_method<1>(type, "transform_vector", [](VM* vm, ArgsView args){ vm->bind_method<1>(type, "transform_vector", [](VM* vm, ArgsView args){
const Mat3x3& self = _CAST(Mat3x3&, args[0]); const Mat3x3& self = _CAST(Mat3x3&, args[0]);
Vec2 v = CAST(Vec2, args[1]); Vec2 v = CAST(Vec2, args[1]);
Vec2 res(self._11 * v.x + self._12 * v.y, self._21 * v.x + self._22 * v.y); Vec2 res(self._11 * v.x + self._12 * v.y, self._21 * v.x + self._22 * v.y);
return VAR_T(Vec2, res); return vm->new_user_object<Vec2>(res);
}); });
vm->bind_method<1>(type, "inverse_transform_vector", [](VM* vm, ArgsView args){ vm->bind_method<1>(type, "inverse_transform_vector", [](VM* vm, ArgsView args){
@ -533,7 +533,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
Mat3x3 inv; Mat3x3 inv;
if(!self.inverse(inv)) vm->ValueError("matrix is not invertible"); if(!self.inverse(inv)) vm->ValueError("matrix is not invertible");
Vec2 res(inv._11 * v.x + inv._12 * v.y, inv._21 * v.x + inv._22 * v.y); Vec2 res(inv._11 * v.x + inv._12 * v.y, inv._21 * v.x + inv._22 * v.y);
return VAR_T(Vec2, res); return vm->new_user_object<Vec2>(res);
}); });
} }

View File

@ -75,7 +75,7 @@ void add_module_time(VM* vm){
vm->bind_func<0>(mod, "localtime", [](VM* vm, ArgsView args) { vm->bind_func<0>(mod, "localtime", [](VM* vm, ArgsView args) {
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now); std::time_t t = std::chrono::system_clock::to_time_t(now);
return VAR_T(PyStructTime, t); return vm->new_user_object<PyStructTime>(t);
}); });
} }

View File

@ -371,7 +371,7 @@ void init_builtins(VM* _vm) {
return VAR(r); return VAR(r);
}); });
_vm->bind__iter__(VM::tp_range, [](VM* vm, PyObject* obj) { return VAR_T(RangeIter, PK_OBJ_GET(Range, obj)); }); _vm->bind__iter__(VM::tp_range, [](VM* vm, PyObject* obj) { return vm->new_user_object<RangeIter>(PK_OBJ_GET(Range, obj)); });
// tp_nonetype // tp_nonetype
_vm->bind__repr__(_vm->_tp(_vm->None), [](VM* vm, PyObject* _0) { _vm->bind__repr__(_vm->_tp(_vm->None), [](VM* vm, PyObject* _0) {
@ -567,7 +567,7 @@ void init_builtins(VM* _vm) {
return VAR(self.index(CAST(Str&, _1)) != -1); return VAR(self.index(CAST(Str&, _1)) != -1);
}); });
_vm->bind__str__(VM::tp_str, [](VM* vm, PyObject* _0) { return _0; }); _vm->bind__str__(VM::tp_str, [](VM* vm, PyObject* _0) { return _0; });
_vm->bind__iter__(VM::tp_str, [](VM* vm, PyObject* _0) { return VAR_T(StringIter, _0); }); _vm->bind__iter__(VM::tp_str, [](VM* vm, PyObject* _0) { return vm->new_user_object<StringIter>(_0); });
_vm->bind__repr__(VM::tp_str, [](VM* vm, PyObject* _0) { _vm->bind__repr__(VM::tp_str, [](VM* vm, PyObject* _0) {
const Str& self = _CAST(Str&, _0); const Str& self = _CAST(Str&, _0);
return VAR(self.escape()); return VAR(self.escape());
@ -993,7 +993,7 @@ void init_builtins(VM* _vm) {
}); });
_vm->bind__iter__(VM::tp_list, [](VM* vm, PyObject* _0) { _vm->bind__iter__(VM::tp_list, [](VM* vm, PyObject* _0) {
List& self = _CAST(List&, _0); List& self = _CAST(List&, _0);
return VAR_T(ArrayIter, _0, self.begin(), self.end()); return vm->new_user_object<ArrayIter>(_0, self.begin(), self.end());
}); });
_vm->bind__getitem__(VM::tp_list, PyArrayGetItem<List>); _vm->bind__getitem__(VM::tp_list, PyArrayGetItem<List>);
_vm->bind__setitem__(VM::tp_list, [](VM* vm, PyObject* _0, PyObject* _1, PyObject* _2){ _vm->bind__setitem__(VM::tp_list, [](VM* vm, PyObject* _0, PyObject* _1, PyObject* _2){
@ -1055,7 +1055,7 @@ void init_builtins(VM* _vm) {
_vm->bind__iter__(VM::tp_tuple, [](VM* vm, PyObject* _0) { _vm->bind__iter__(VM::tp_tuple, [](VM* vm, PyObject* _0) {
Tuple& self = _CAST(Tuple&, _0); Tuple& self = _CAST(Tuple&, _0);
return VAR_T(ArrayIter, _0, self.begin(), self.end()); return vm->new_user_object<ArrayIter>(_0, self.begin(), self.end());
}); });
_vm->bind__getitem__(VM::tp_tuple, PyArrayGetItem<Tuple>); _vm->bind__getitem__(VM::tp_tuple, PyArrayGetItem<Tuple>);
_vm->bind__len__(VM::tp_tuple, [](VM* vm, PyObject* obj) { _vm->bind__len__(VM::tp_tuple, [](VM* vm, PyObject* obj) {