Browse Source

replace `PyObject*` with `PyVar`

blueloveTH 1 year ago
parent
commit
82d192e8da
23 changed files with 604 additions and 604 deletions
  1. 26 26
      src/array2d.cpp
  2. 1 1
      src/base64.cpp
  3. 141 141
      src/ceval.cpp
  4. 16 16
      src/cffi.cpp
  5. 4 4
      src/codeobject.cpp
  6. 9 9
      src/collections.cpp
  7. 7 7
      src/compiler.cpp
  8. 3 3
      src/csv.cpp
  9. 7 7
      src/dataclasses.cpp
  10. 6 6
      src/dict.cpp
  11. 1 1
      src/easing.cpp
  12. 1 1
      src/expr.cpp
  13. 4 4
      src/frame.cpp
  14. 5 5
      src/gc.cpp
  15. 5 5
      src/io.cpp
  16. 20 20
      src/iter.cpp
  17. 23 23
      src/linalg.cpp
  18. 22 22
      src/modules.cpp
  19. 120 120
      src/pocketpy.cpp
  20. 40 40
      src/pocketpy_c.cpp
  21. 4 4
      src/random.cpp
  22. 4 4
      src/tuplelist.cpp
  23. 135 135
      src/vm.cpp

+ 26 - 26
src/array2d.cpp

@@ -5,7 +5,7 @@ namespace pkpy{
 struct Array2d{
 struct Array2d{
     PK_ALWAYS_PASS_BY_POINTER(Array2d)
     PK_ALWAYS_PASS_BY_POINTER(Array2d)
 
 
-    PyObject** data;
+    PyVar* data;
     int n_cols;
     int n_cols;
     int n_rows;
     int n_rows;
     int numel;
     int numel;
@@ -21,22 +21,22 @@ struct Array2d{
         this->n_cols = n_cols;
         this->n_cols = n_cols;
         this->n_rows = n_rows;
         this->n_rows = n_rows;
         this->numel = n_cols * n_rows;
         this->numel = n_cols * n_rows;
-        this->data = new PyObject*[numel];
+        this->data = new PyVar[numel];
     }
     }
 
 
     bool is_valid(int col, int row) const{
     bool is_valid(int col, int row) const{
         return 0 <= col && col < n_cols && 0 <= row && row < n_rows;
         return 0 <= col && col < n_cols && 0 <= row && row < n_rows;
     }
     }
 
 
-    PyObject* _get(int col, int row){
+    PyVar _get(int col, int row){
         return data[row * n_cols + col];
         return data[row * n_cols + col];
     }
     }
 
 
-    void _set(int col, int row, PyObject* value){
+    void _set(int col, int row, PyVar value){
         data[row * n_cols + col] = value;
         data[row * n_cols + col] = value;
     }
     }
 
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type){
+    static void _register(VM* vm, PyVar mod, PyVar type){
         vm->bind(type, "__new__(cls, *args, **kwargs)", [](VM* vm, ArgsView args){
         vm->bind(type, "__new__(cls, *args, **kwargs)", [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             Type cls = PK_OBJ_GET(Type, args[0]);
             return vm->heap.gcnew<Array2d>(cls);
             return vm->heap.gcnew<Array2d>(cls);
@@ -89,7 +89,7 @@ struct Array2d{
                 int slice_height = stop_row - start_row;    \
                 int slice_height = stop_row - start_row;    \
                 if(slice_width <= 0 || slice_height <= 0) vm->ValueError("slice width and height must be positive");
                 if(slice_width <= 0 || slice_height <= 0) vm->ValueError("slice width and height must be positive");
 
 
-        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
+        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             const Tuple& xy = CAST(Tuple&, _1);
             const Tuple& xy = CAST(Tuple&, _1);
             i64 col, row;
             i64 col, row;
@@ -102,7 +102,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->new_user_object<Array2d>();
+                PyVar 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++){
@@ -116,7 +116,7 @@ struct Array2d{
             PK_UNREACHABLE();
             PK_UNREACHABLE();
         });
         });
 
 
-        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1, PyObject* _2){
+        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1, PyVar _2){
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             const Tuple& xy = CAST(Tuple&, _1);
             const Tuple& xy = CAST(Tuple&, _1);
             i64 col, row;
             i64 col, row;
@@ -176,20 +176,20 @@ struct Array2d{
             return VAR(std::move(t));
             return VAR(std::move(t));
         });
         });
 
 
-        vm->bind__len__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0){
+        vm->bind__len__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0){
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             return (i64)self.numel;
             return (i64)self.numel;
         });
         });
 
 
-        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) -> Str{
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) -> Str{
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             return _S("array2d(", self.n_cols, ", ", self.n_rows, ')');
             return _S("array2d(", self.n_cols, ", ", self.n_rows, ')');
         });
         });
 
 
         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* new_array_obj = vm->new_user_object<Array2d>();
+            PyVar f = args[1];
+            PyVar 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++){
@@ -200,7 +200,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->new_user_object<Array2d>();
+            PyVar 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++){
@@ -219,7 +219,7 @@ struct Array2d{
 
 
         vm->bind(type, "apply_(self, f)", [](VM* vm, ArgsView args){
         vm->bind(type, "apply_(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];
+            PyVar f = args[1];
             for(int i = 0; i < self.numel; i++){
             for(int i = 0; i < self.numel; i++){
                 self.data[i] = vm->call(f, self.data[i]);
                 self.data[i] = vm->call(f, self.data[i]);
             }
             }
@@ -250,7 +250,7 @@ struct Array2d{
             return vm->None;
             return vm->None;
         });
         });
 
 
-        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
+        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             Array2d& self = PK_OBJ_GET(Array2d, _0);
             if(!vm->is_user_type<Array2d>(_1)) 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);
@@ -263,10 +263,10 @@ 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->new_user_object<Array2d>();
+            PyVar 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];
+            PyVar value = args[1];
             const Str& neighborhood = CAST(Str&, args[2]);
             const Str& neighborhood = CAST(Str&, args[2]);
             if(neighborhood == "Moore"){
             if(neighborhood == "Moore"){
                 for(int j = 0; j < new_array.n_rows; j++){
                 for(int j = 0; j < new_array.n_rows; j++){
@@ -302,7 +302,7 @@ struct Array2d{
 
 
         vm->bind(type, "count(self, value) -> int", [](VM* vm, ArgsView args){
         vm->bind(type, "count(self, value) -> int", [](VM* vm, ArgsView args){
             Array2d& self = PK_OBJ_GET(Array2d, args[0]);
             Array2d& self = PK_OBJ_GET(Array2d, args[0]);
-            PyObject* value = args[1];
+            PyVar value = args[1];
             int count = 0;
             int count = 0;
             for(int i = 0; i < self.numel; i++) count += vm->py_eq(self.data[i], value);
             for(int i = 0; i < self.numel; i++) count += vm->py_eq(self.data[i], value);
             return VAR(count);
             return VAR(count);
@@ -310,7 +310,7 @@ struct Array2d{
 
 
         vm->bind(type, "find_bounding_rect(self, value)", [](VM* vm, ArgsView args){
         vm->bind(type, "find_bounding_rect(self, value)", [](VM* vm, ArgsView args){
             Array2d& self = PK_OBJ_GET(Array2d, args[0]);
             Array2d& self = PK_OBJ_GET(Array2d, args[0]);
-            PyObject* value = args[1];
+            PyVar value = args[1];
             int left = self.n_cols;
             int left = self.n_cols;
             int top = self.n_rows;
             int top = self.n_rows;
             int right = 0;
             int right = 0;
@@ -345,15 +345,15 @@ struct Array2d{
 struct Array2dIter{
 struct Array2dIter{
     PK_ALWAYS_PASS_BY_POINTER(Array2dIter)
     PK_ALWAYS_PASS_BY_POINTER(Array2dIter)
 
 
-    PyObject* ref;
+    PyVar ref;
     int i;
     int i;
-    Array2dIter(PyObject* ref) : ref(ref), i(0) {}
+    Array2dIter(PyVar ref) : ref(ref), i(0) {}
 
 
     void _gc_mark() const{ PK_OBJ_MARK(ref); }
     void _gc_mark() const{ PK_OBJ_MARK(ref); }
 
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) { return _0; });
-        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) -> unsigned{
+    static void _register(VM* vm, PyVar mod, PyVar type){
+        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) { return _0; });
+        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) -> unsigned{
             Array2dIter& self = PK_OBJ_GET(Array2dIter, _0);
             Array2dIter& self = PK_OBJ_GET(Array2dIter, _0);
             Array2d& a = PK_OBJ_GET(Array2d, self.ref);
             Array2d& a = PK_OBJ_GET(Array2d, self.ref);
             if(self.i == a.numel) return 0;
             if(self.i == a.numel) return 0;
@@ -367,12 +367,12 @@ struct Array2dIter{
 };
 };
 
 
 void add_module_array2d(VM* vm){
 void add_module_array2d(VM* vm){
-    PyObject* mod = vm->new_module("array2d");
+    PyVar mod = vm->new_module("array2d");
 
 
     vm->register_user_class<Array2d>(mod, "array2d", VM::tp_object, true);
     vm->register_user_class<Array2d>(mod, "array2d", VM::tp_object, true);
     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, PyVar _0){
         return vm->new_user_object<Array2dIter>(_0);
         return vm->new_user_object<Array2dIter>(_0);
     });
     });
 }
 }

+ 1 - 1
src/base64.cpp

@@ -166,7 +166,7 @@ base64_decode(const char *in, unsigned int inlen, unsigned char *out)
 }
 }
 
 
 void add_module_base64(VM* vm){
 void add_module_base64(VM* vm){
-    PyObject* mod = vm->new_module("base64");
+    PyVar mod = vm->new_module("base64");
 
 
     // b64encode
     // b64encode
     vm->bind_func(mod, "b64encode", 1, [](VM* vm, ArgsView args){
     vm->bind_func(mod, "b64encode", 1, [](VM* vm, ArgsView args){

+ 141 - 141
src/ceval.cpp

@@ -10,25 +10,25 @@ namespace pkpy{
 
 
 #define PREDICT_INT_DIV_OP(op)  \
 #define PREDICT_INT_DIV_OP(op)  \
     if(is_small_int(_0) && is_small_int(_1)){   \
     if(is_small_int(_0) && is_small_int(_1)){   \
-        if(_1 == (PyObject*)0b10) ZeroDivisionError();   \
+        if(_1 == (PyVar)0b10) ZeroDivisionError();   \
         TOP() = VAR((PK_BITS(_0)>>2) op (PK_BITS(_1)>>2)); \
         TOP() = VAR((PK_BITS(_0)>>2) op (PK_BITS(_1)>>2)); \
         DISPATCH() \
         DISPATCH() \
     }
     }
 
 
 #define BINARY_F_COMPARE(func, op, rfunc)                           \
 #define BINARY_F_COMPARE(func, op, rfunc)                           \
-        PyObject* ret;                                              \
+        PyVar ret;                                              \
         const PyTypeInfo* _ti = _tp_info(_0);                \
         const PyTypeInfo* _ti = _tp_info(_0);                \
         if(_ti->m##func){                               \
         if(_ti->m##func){                               \
             ret = _ti->m##func(this, _0, _1);           \
             ret = _ti->m##func(this, _0, _1);           \
         }else{                                          \
         }else{                                          \
-            PyObject* self;                                                     \
-            PyObject* _2 = get_unbound_method(_0, func, &self, false);          \
+            PyVar self;                                                     \
+            PyVar _2 = get_unbound_method(_0, func, &self, false);          \
             if(_2 != nullptr) ret = call_method(self, _2, _1);                  \
             if(_2 != nullptr) ret = call_method(self, _2, _1);                  \
             else ret = NotImplemented;                                          \
             else ret = NotImplemented;                                          \
         }                                                                       \
         }                                                                       \
         if(ret == NotImplemented){                                              \
         if(ret == NotImplemented){                                              \
-            PyObject* self;                                                     \
-            PyObject* _2 = get_unbound_method(_1, rfunc, &self, false);         \
+            PyVar self;                                                     \
+            PyVar _2 = get_unbound_method(_1, rfunc, &self, false);         \
             if(_2 != nullptr) ret = call_method(self, _2, _0);                  \
             if(_2 != nullptr) ret = call_method(self, _2, _0);                  \
             else BinaryOptError(op, _0, _1);                                    \
             else BinaryOptError(op, _0, _1);                                    \
             if(ret == NotImplemented) BinaryOptError(op, _0, _1);               \
             if(ret == NotImplemented) BinaryOptError(op, _0, _1);               \
@@ -36,12 +36,12 @@ namespace pkpy{
 
 
 
 
 void VM::__op_unpack_sequence(uint16_t arg){
 void VM::__op_unpack_sequence(uint16_t arg){
-    PyObject* _0 = POPX();
+    PyVar _0 = POPX();
     if(is_type(_0, VM::tp_tuple)){
     if(is_type(_0, VM::tp_tuple)){
         // fast path for tuple
         // fast path for tuple
         Tuple& tuple = PK_OBJ_GET(Tuple, _0);
         Tuple& tuple = PK_OBJ_GET(Tuple, _0);
         if(tuple.size() == arg){
         if(tuple.size() == arg){
-            for(PyObject* obj: tuple) PUSH(obj);
+            for(PyVar obj: tuple) PUSH(obj);
         }else{
         }else{
             ValueError(_S("expected ", (int)arg, " values to unpack, got ", (int)tuple.size()));
             ValueError(_S("expected ", (int)arg, " values to unpack, got ", (int)tuple.size()));
         }
         }
@@ -50,7 +50,7 @@ void VM::__op_unpack_sequence(uint16_t arg){
         _0 = py_iter(_0);
         _0 = py_iter(_0);
         const PyTypeInfo* ti = _tp_info(_0);
         const PyTypeInfo* ti = _tp_info(_0);
         for(int i=0; i<arg; i++){
         for(int i=0; i<arg; i++){
-            PyObject* _1 = _py_next(ti, _0);
+            PyVar _1 = _py_next(ti, _0);
             if(_1 == StopIteration) ValueError("not enough values to unpack");
             if(_1 == StopIteration) ValueError("not enough values to unpack");
             PUSH(_1);
             PUSH(_1);
         }
         }
@@ -58,29 +58,29 @@ void VM::__op_unpack_sequence(uint16_t arg){
     }
     }
 }
 }
 
 
-bool VM::py_lt(PyObject* _0, PyObject* _1){
+bool VM::py_lt(PyVar _0, PyVar _1){
     BINARY_F_COMPARE(__lt__, "<", __gt__);
     BINARY_F_COMPARE(__lt__, "<", __gt__);
     return ret == True;
     return ret == True;
 }
 }
 
 
-bool VM::py_le(PyObject* _0, PyObject* _1){
+bool VM::py_le(PyVar _0, PyVar _1){
     BINARY_F_COMPARE(__le__, "<=", __ge__);
     BINARY_F_COMPARE(__le__, "<=", __ge__);
     return ret == True;
     return ret == True;
 }
 }
 
 
-bool VM::py_gt(PyObject* _0, PyObject* _1){
+bool VM::py_gt(PyVar _0, PyVar _1){
     BINARY_F_COMPARE(__gt__, ">", __lt__);
     BINARY_F_COMPARE(__gt__, ">", __lt__);
     return ret == True;
     return ret == True;
 }
 }
 
 
-bool VM::py_ge(PyObject* _0, PyObject* _1){
+bool VM::py_ge(PyVar _0, PyVar _1){
     BINARY_F_COMPARE(__ge__, ">=", __le__);
     BINARY_F_COMPARE(__ge__, ">=", __le__);
     return ret == True;
     return ret == True;
 }
 }
 
 
 #undef BINARY_F_COMPARE
 #undef BINARY_F_COMPARE
 
 
-PyObject* VM::__run_top_frame(){
+PyVar VM::__run_top_frame(){
     Frame* frame = &callstack.top();
     Frame* frame = &callstack.top();
     const Frame* base_frame = frame;
     const Frame* base_frame = frame;
     bool need_raise = false;
     bool need_raise = false;
@@ -91,7 +91,7 @@ PyObject* VM::__run_top_frame(){
 /**********************************************************************/
 /**********************************************************************/
 /* NOTE: 
 /* NOTE: 
  * Be aware of accidental gc!
  * Be aware of accidental gc!
- * DO NOT leave any strong reference of PyObject* in the C stack
+ * DO NOT leave any strong reference of PyVar in the C stack
  */
  */
 {
 {
 
 
@@ -128,7 +128,7 @@ __NEXT_STEP:;
     case OP_DUP_TOP: PUSH(TOP()); DISPATCH()
     case OP_DUP_TOP: PUSH(TOP()); DISPATCH()
     case OP_ROT_TWO: std::swap(TOP(), SECOND()); DISPATCH()
     case OP_ROT_TWO: std::swap(TOP(), SECOND()); DISPATCH()
     case OP_ROT_THREE:{
     case OP_ROT_THREE:{
-        PyObject* _0 = TOP();
+        PyVar _0 = TOP();
         TOP() = SECOND();
         TOP() = SECOND();
         SECOND() = THIRD();
         SECOND() = THIRD();
         THIRD() = _0;
         THIRD() = _0;
@@ -145,12 +145,12 @@ __NEXT_STEP:;
     case OP_LOAD_TRUE:       PUSH(True); DISPATCH()
     case OP_LOAD_TRUE:       PUSH(True); DISPATCH()
     case OP_LOAD_FALSE:      PUSH(False); DISPATCH()
     case OP_LOAD_FALSE:      PUSH(False); DISPATCH()
     /*****************************************/
     /*****************************************/
-    case OP_LOAD_SMALL_INT:  PUSH((PyObject*)(uintptr_t)byte.arg); DISPATCH()
+    case OP_LOAD_SMALL_INT:  PUSH((PyVar)(uintptr_t)byte.arg); DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_LOAD_ELLIPSIS:   PUSH(Ellipsis); DISPATCH()
     case OP_LOAD_ELLIPSIS:   PUSH(Ellipsis); DISPATCH()
     case OP_LOAD_FUNCTION: {
     case OP_LOAD_FUNCTION: {
         const FuncDecl_& decl = co->func_decls[byte.arg];
         const FuncDecl_& decl = co->func_decls[byte.arg];
-        PyObject* obj;
+        PyVar obj;
         if(decl->nested){
         if(decl->nested){
             NameDict_ captured = frame->_locals.to_namedict();
             NameDict_ captured = frame->_locals.to_namedict();
             obj = VAR(Function(decl, frame->_module, nullptr, captured));
             obj = VAR(Function(decl, frame->_module, nullptr, captured));
@@ -163,19 +163,19 @@ __NEXT_STEP:;
     case OP_LOAD_NULL: PUSH(PY_NULL); DISPATCH()
     case OP_LOAD_NULL: PUSH(PY_NULL); DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_LOAD_FAST: {
     case OP_LOAD_FAST: {
-        PyObject* _0 = frame->_locals[byte.arg];
+        PyVar _0 = frame->_locals[byte.arg];
         if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
         if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_LOAD_NAME: {
     case OP_LOAD_NAME: {
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject** slot = frame->_locals.try_get_name(_name);
+        PyVar* slot = frame->_locals.try_get_name(_name);
         if(slot != nullptr) {
         if(slot != nullptr) {
             if(*slot == PY_NULL) vm->UnboundLocalError(_name);
             if(*slot == PY_NULL) vm->UnboundLocalError(_name);
             PUSH(*slot);
             PUSH(*slot);
             DISPATCH()
             DISPATCH()
         }
         }
-        PyObject* _0 = frame->f_closure_try_get(_name);
+        PyVar _0 = frame->f_closure_try_get(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         _0 = frame->f_globals().try_get_likely_found(_name);
         _0 = frame->f_globals().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
@@ -185,7 +185,7 @@ __NEXT_STEP:;
     } DISPATCH()
     } DISPATCH()
     case OP_LOAD_NONLOCAL: {
     case OP_LOAD_NONLOCAL: {
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject* _0 = frame->f_closure_try_get(_name);
+        PyVar _0 = frame->f_closure_try_get(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         _0 = frame->f_globals().try_get_likely_found(_name);
         _0 = frame->f_globals().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
@@ -195,7 +195,7 @@ __NEXT_STEP:;
     } DISPATCH()
     } DISPATCH()
     case OP_LOAD_GLOBAL:{
     case OP_LOAD_GLOBAL:{
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject* _0 = frame->f_globals().try_get_likely_found(_name);
+        PyVar _0 = frame->f_globals().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         _0 = vm->builtins->attr().try_get_likely_found(_name);
         _0 = vm->builtins->attr().try_get_likely_found(_name);
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
@@ -207,7 +207,7 @@ __NEXT_STEP:;
     case OP_LOAD_CLASS_GLOBAL:{
     case OP_LOAD_CLASS_GLOBAL:{
         PK_ASSERT(__curr_class != nullptr);
         PK_ASSERT(__curr_class != nullptr);
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject* _0 = getattr(__curr_class, _name, false);
+        PyVar _0 = getattr(__curr_class, _name, false);
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         if(_0 != nullptr) { PUSH(_0); DISPATCH() }
         // load global if attribute not found
         // load global if attribute not found
         _0 = frame->f_globals().try_get_likely_found(_name);
         _0 = frame->f_globals().try_get_likely_found(_name);
@@ -217,13 +217,13 @@ __NEXT_STEP:;
         vm->NameError(_name);
         vm->NameError(_name);
     } DISPATCH()
     } DISPATCH()
     case OP_LOAD_METHOD:{
     case OP_LOAD_METHOD:{
-        PyObject* _0;
+        PyVar _0;
         TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
         TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true);
         PUSH(_0);
         PUSH(_0);
     }DISPATCH()
     }DISPATCH()
     case OP_LOAD_SUBSCR:{
     case OP_LOAD_SUBSCR:{
-        PyObject* _1 = POPX();    // b
-        PyObject* _0 = TOP();     // a
+        PyVar _1 = POPX();    // b
+        PyVar _0 = TOP();     // a
         auto _ti = _tp_info(_0);
         auto _ti = _tp_info(_0);
         if(_ti->m__getitem__){
         if(_ti->m__getitem__){
             TOP() = _ti->m__getitem__(this, _0, _1);
             TOP() = _ti->m__getitem__(this, _0, _1);
@@ -232,9 +232,9 @@ __NEXT_STEP:;
         }
         }
     } DISPATCH()
     } DISPATCH()
     case OP_LOAD_SUBSCR_FAST:{
     case OP_LOAD_SUBSCR_FAST:{
-        PyObject* _1 = frame->_locals[byte.arg];
+        PyVar _1 = frame->_locals[byte.arg];
         if(_1 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
         if(_1 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
-        PyObject* _0 = TOP();     // a
+        PyVar _0 = TOP();     // a
         auto _ti = _tp_info(_0);
         auto _ti = _tp_info(_0);
         if(_ti->m__getitem__){
         if(_ti->m__getitem__){
             TOP() = _ti->m__getitem__(this, _0, _1);
             TOP() = _ti->m__getitem__(this, _0, _1);
@@ -243,8 +243,8 @@ __NEXT_STEP:;
         }
         }
     } DISPATCH()
     } DISPATCH()
     case OP_LOAD_SUBSCR_SMALL_INT:{
     case OP_LOAD_SUBSCR_SMALL_INT:{
-        PyObject* _1 = (PyObject*)(uintptr_t)byte.arg;
-        PyObject* _0 = TOP();     // a
+        PyVar _1 = (PyVar)(uintptr_t)byte.arg;
+        PyVar _0 = TOP();     // a
         auto _ti = _tp_info(_0);
         auto _ti = _tp_info(_0);
         if(_ti->m__getitem__){
         if(_ti->m__getitem__){
             TOP() = _ti->m__getitem__(this, _0, _1);
             TOP() = _ti->m__getitem__(this, _0, _1);
@@ -257,9 +257,9 @@ __NEXT_STEP:;
         DISPATCH()
         DISPATCH()
     case OP_STORE_NAME:{
     case OP_STORE_NAME:{
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject* _0 = POPX();
+        PyVar _0 = POPX();
         if(frame->_callable != nullptr){
         if(frame->_callable != nullptr){
-            PyObject** slot = frame->_locals.try_get_name(_name);
+            PyVar* slot = frame->_locals.try_get_name(_name);
             if(slot != nullptr){
             if(slot != nullptr){
                 *slot = _0;     // store in locals if possible
                 *slot = _0;     // store in locals if possible
             }else{
             }else{
@@ -279,15 +279,15 @@ __NEXT_STEP:;
         frame->f_globals().set(StrName(byte.arg), POPX());
         frame->f_globals().set(StrName(byte.arg), POPX());
         DISPATCH()
         DISPATCH()
     case OP_STORE_ATTR: {
     case OP_STORE_ATTR: {
-        PyObject* _0 = TOP();         // a
-        PyObject* _1 = SECOND();      // val
+        PyVar _0 = TOP();         // a
+        PyVar _1 = SECOND();      // val
         setattr(_0, StrName(byte.arg), _1);
         setattr(_0, StrName(byte.arg), _1);
         STACK_SHRINK(2);
         STACK_SHRINK(2);
     } DISPATCH()
     } DISPATCH()
     case OP_STORE_SUBSCR:{
     case OP_STORE_SUBSCR:{
-        PyObject* _2 = POPX();        // b
-        PyObject* _1 = POPX();        // a
-        PyObject* _0 = POPX();        // val
+        PyVar _2 = POPX();        // b
+        PyVar _1 = POPX();        // a
+        PyVar _0 = POPX();        // val
         auto _ti = _tp_info(_1);
         auto _ti = _tp_info(_1);
         if(_ti->m__setitem__){
         if(_ti->m__setitem__){
             _ti->m__setitem__(this, _1, _2, _0);
             _ti->m__setitem__(this, _1, _2, _0);
@@ -296,10 +296,10 @@ __NEXT_STEP:;
         }
         }
     }DISPATCH()
     }DISPATCH()
     case OP_STORE_SUBSCR_FAST:{
     case OP_STORE_SUBSCR_FAST:{
-        PyObject* _2 = frame->_locals[byte.arg];    // b
+        PyVar _2 = frame->_locals[byte.arg];    // b
         if(_2 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
         if(_2 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
-        PyObject* _1 = POPX();        // a
-        PyObject* _0 = POPX();        // val
+        PyVar _1 = POPX();        // a
+        PyVar _0 = POPX();        // val
         auto _ti = _tp_info(_1);
         auto _ti = _tp_info(_1);
         if(_ti->m__setitem__){
         if(_ti->m__setitem__){
             _ti->m__setitem__(this, _1, _2, _0);
             _ti->m__setitem__(this, _1, _2, _0);
@@ -308,14 +308,14 @@ __NEXT_STEP:;
         }
         }
     }DISPATCH()
     }DISPATCH()
     case OP_DELETE_FAST:{
     case OP_DELETE_FAST:{
-        PyObject* _0 = frame->_locals[byte.arg];
+        PyVar _0 = frame->_locals[byte.arg];
         if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
         if(_0 == PY_NULL) vm->UnboundLocalError(co->varnames[byte.arg]);
         frame->_locals[byte.arg] = PY_NULL;
         frame->_locals[byte.arg] = PY_NULL;
     }DISPATCH()
     }DISPATCH()
     case OP_DELETE_NAME:{
     case OP_DELETE_NAME:{
         StrName _name(byte.arg);
         StrName _name(byte.arg);
         if(frame->_callable != nullptr){
         if(frame->_callable != nullptr){
-            PyObject** slot = frame->_locals.try_get_name(_name);
+            PyVar* slot = frame->_locals.try_get_name(_name);
             if(slot != nullptr){
             if(slot != nullptr){
                 *slot = PY_NULL;
                 *slot = PY_NULL;
             }else{
             }else{
@@ -337,12 +337,12 @@ __NEXT_STEP:;
         if(!frame->f_globals().del(_name)) vm->NameError(_name);
         if(!frame->f_globals().del(_name)) vm->NameError(_name);
     }DISPATCH()
     }DISPATCH()
     case OP_DELETE_ATTR:{
     case OP_DELETE_ATTR:{
-        PyObject* _0 = POPX();
+        PyVar _0 = POPX();
         delattr(_0, StrName(byte.arg));
         delattr(_0, StrName(byte.arg));
     } DISPATCH()
     } DISPATCH()
     case OP_DELETE_SUBSCR:{
     case OP_DELETE_SUBSCR:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = POPX();
+        PyVar _1 = POPX();
+        PyVar _0 = POPX();
         auto _ti = _tp_info(_0);
         auto _ti = _tp_info(_0);
         if(_ti->m__delitem__){
         if(_ti->m__delitem__){
             _ti->m__delitem__(this, _0, _1);
             _ti->m__delitem__(this, _0, _1);
@@ -352,12 +352,12 @@ __NEXT_STEP:;
     }DISPATCH()
     }DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_BUILD_LONG: {
     case OP_BUILD_LONG: {
-        PyObject* _0 = builtins->attr().try_get_likely_found(pk_id_long);
+        PyVar _0 = builtins->attr().try_get_likely_found(pk_id_long);
         if(_0 == nullptr) AttributeError(builtins, pk_id_long);
         if(_0 == nullptr) AttributeError(builtins, pk_id_long);
         TOP() = call(_0, TOP());
         TOP() = call(_0, TOP());
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_IMAG: {
     case OP_BUILD_IMAG: {
-        PyObject* _0 = builtins->attr().try_get_likely_found(pk_id_complex);
+        PyVar _0 = builtins->attr().try_get_likely_found(pk_id_complex);
         if(_0 == nullptr) AttributeError(builtins, pk_id_long);
         if(_0 == nullptr) AttributeError(builtins, pk_id_long);
         TOP() = call(_0, VAR(0), TOP());
         TOP() = call(_0, VAR(0), TOP());
     } DISPATCH()
     } DISPATCH()
@@ -368,12 +368,12 @@ __NEXT_STEP:;
         TOP() = VAR(Bytes(p, s.size));
         TOP() = VAR(Bytes(p, s.size));
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_TUPLE:{
     case OP_BUILD_TUPLE:{
-        PyObject* _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
+        PyVar _0 = VAR(STACK_VIEW(byte.arg).to_tuple());
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_LIST:{
     case OP_BUILD_LIST:{
-        PyObject* _0 = VAR(STACK_VIEW(byte.arg).to_list());
+        PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
@@ -382,27 +382,27 @@ __NEXT_STEP:;
             PUSH(VAR(Dict(this)));
             PUSH(VAR(Dict(this)));
             DISPATCH()
             DISPATCH()
         }
         }
-        PyObject* _0 = VAR(STACK_VIEW(byte.arg).to_list());
+        PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
         _0 = call(_t(tp_dict), _0);
         _0 = call(_t(tp_dict), _0);
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_SET:{
     case OP_BUILD_SET:{
-        PyObject* _0 = VAR(STACK_VIEW(byte.arg).to_list());
+        PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list());
         _0 = call(builtins->attr(pk_id_set), _0);
         _0 = call(builtins->attr(pk_id_set), _0);
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_SLICE:{
     case OP_BUILD_SLICE:{
-        PyObject* _2 = POPX();    // step
-        PyObject* _1 = POPX();    // stop
-        PyObject* _0 = POPX();    // start
+        PyVar _2 = POPX();    // step
+        PyVar _1 = POPX();    // stop
+        PyVar _0 = POPX();    // start
         PUSH(VAR(Slice(_0, _1, _2)));
         PUSH(VAR(Slice(_0, _1, _2)));
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_STRING: {
     case OP_BUILD_STRING: {
         SStream ss;
         SStream ss;
         ArgsView view = STACK_VIEW(byte.arg);
         ArgsView view = STACK_VIEW(byte.arg);
-        for(PyObject* obj : view) ss << py_str(obj);
+        for(PyVar obj : view) ss << py_str(obj);
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
         PUSH(VAR(ss.str()));
         PUSH(VAR(ss.str()));
     } DISPATCH()
     } DISPATCH()
@@ -412,7 +412,7 @@ __NEXT_STEP:;
         List list;
         List list;
         __unpack_as_list(STACK_VIEW(byte.arg), list);
         __unpack_as_list(STACK_VIEW(byte.arg), list);
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
-        PyObject* _0 = VAR(Tuple(std::move(list)));
+        PyVar _0 = VAR(Tuple(std::move(list)));
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_LIST_UNPACK: {
     case OP_BUILD_LIST_UNPACK: {
@@ -420,7 +420,7 @@ __NEXT_STEP:;
         List list;
         List list;
         __unpack_as_list(STACK_VIEW(byte.arg), list);
         __unpack_as_list(STACK_VIEW(byte.arg), list);
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
-        PyObject* _0 = VAR(std::move(list));
+        PyVar _0 = VAR(std::move(list));
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_DICT_UNPACK: {
     case OP_BUILD_DICT_UNPACK: {
@@ -428,7 +428,7 @@ __NEXT_STEP:;
         Dict dict(this);
         Dict dict(this);
         __unpack_as_dict(STACK_VIEW(byte.arg), dict);
         __unpack_as_dict(STACK_VIEW(byte.arg), dict);
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
-        PyObject* _0 = VAR(std::move(dict));
+        PyVar _0 = VAR(std::move(dict));
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_BUILD_SET_UNPACK: {
     case OP_BUILD_SET_UNPACK: {
@@ -436,7 +436,7 @@ __NEXT_STEP:;
         List list;
         List list;
         __unpack_as_list(STACK_VIEW(byte.arg), list);
         __unpack_as_list(STACK_VIEW(byte.arg), list);
         STACK_SHRINK(byte.arg);
         STACK_SHRINK(byte.arg);
-        PyObject* _0 = VAR(std::move(list));
+        PyVar _0 = VAR(std::move(list));
         _0 = call(builtins->attr(pk_id_set), _0);
         _0 = call(builtins->attr(pk_id_set), _0);
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
@@ -446,152 +446,152 @@ __NEXT_STEP:;
         if(_ti->m##func){                               \
         if(_ti->m##func){                               \
             TOP() = _ti->m##func(this, _0, _1);         \
             TOP() = _ti->m##func(this, _0, _1);         \
         }else{                                          \
         }else{                                          \
-            PyObject* self;                                         \
-            PyObject* _2 = get_unbound_method(_0, func, &self, false);        \
+            PyVar self;                                         \
+            PyVar _2 = get_unbound_method(_0, func, &self, false);        \
             if(_2 != nullptr) TOP() = call_method(self, _2, _1);    \
             if(_2 != nullptr) TOP() = call_method(self, _2, _1);    \
             else TOP() = NotImplemented;                            \
             else TOP() = NotImplemented;                            \
         }
         }
 
 
 #define BINARY_OP_RSPECIAL(op, func)                                \
 #define BINARY_OP_RSPECIAL(op, func)                                \
         if(TOP() == NotImplemented){                                \
         if(TOP() == NotImplemented){                                \
-            PyObject* self;                                         \
-            PyObject* _2 = get_unbound_method(_1, func, &self, false);        \
+            PyVar self;                                         \
+            PyVar _2 = get_unbound_method(_1, func, &self, false);        \
             if(_2 != nullptr) TOP() = call_method(self, _2, _0);    \
             if(_2 != nullptr) TOP() = call_method(self, _2, _0);    \
             else BinaryOptError(op, _0, _1);                        \
             else BinaryOptError(op, _0, _1);                        \
             if(TOP() == NotImplemented) BinaryOptError(op, _0, _1); \
             if(TOP() == NotImplemented) BinaryOptError(op, _0, _1); \
         }
         }
 
 
     case OP_BINARY_TRUEDIV:{
     case OP_BINARY_TRUEDIV:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__truediv__);
         BINARY_OP_SPECIAL(__truediv__);
         if(TOP() == NotImplemented) BinaryOptError("/", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("/", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BINARY_POW:{
     case OP_BINARY_POW:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__pow__);
         BINARY_OP_SPECIAL(__pow__);
         if(TOP() == NotImplemented) BinaryOptError("**", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("**", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BINARY_ADD:{
     case OP_BINARY_ADD:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(+)
         PREDICT_INT_OP(+)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__add__);
         BINARY_OP_SPECIAL(__add__);
         BINARY_OP_RSPECIAL("+", __radd__);
         BINARY_OP_RSPECIAL("+", __radd__);
     } DISPATCH()
     } DISPATCH()
     case OP_BINARY_SUB:{
     case OP_BINARY_SUB:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(-)
         PREDICT_INT_OP(-)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__sub__);
         BINARY_OP_SPECIAL(__sub__);
         BINARY_OP_RSPECIAL("-", __rsub__);
         BINARY_OP_RSPECIAL("-", __rsub__);
     } DISPATCH()
     } DISPATCH()
     case OP_BINARY_MUL:{
     case OP_BINARY_MUL:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(*)
         PREDICT_INT_OP(*)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__mul__);
         BINARY_OP_SPECIAL(__mul__);
         BINARY_OP_RSPECIAL("*", __rmul__);
         BINARY_OP_RSPECIAL("*", __rmul__);
     } DISPATCH()
     } DISPATCH()
     case OP_BINARY_FLOORDIV:{
     case OP_BINARY_FLOORDIV:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_DIV_OP(/)
         PREDICT_INT_DIV_OP(/)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__floordiv__);
         BINARY_OP_SPECIAL(__floordiv__);
         if(TOP() == NotImplemented) BinaryOptError("//", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("//", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BINARY_MOD:{
     case OP_BINARY_MOD:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_DIV_OP(%)
         PREDICT_INT_DIV_OP(%)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__mod__);
         BINARY_OP_SPECIAL(__mod__);
         if(TOP() == NotImplemented) BinaryOptError("%", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("%", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_COMPARE_LT:{
     case OP_COMPARE_LT:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(<)
         PREDICT_INT_OP(<)
         TOP() = VAR(py_lt(_0, _1));
         TOP() = VAR(py_lt(_0, _1));
     } DISPATCH()
     } DISPATCH()
     case OP_COMPARE_LE:{
     case OP_COMPARE_LE:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(<=)
         PREDICT_INT_OP(<=)
         TOP() = VAR(py_le(_0, _1));
         TOP() = VAR(py_le(_0, _1));
     } DISPATCH()
     } DISPATCH()
     case OP_COMPARE_EQ:{
     case OP_COMPARE_EQ:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         TOP() = VAR(py_eq(_0, _1));
         TOP() = VAR(py_eq(_0, _1));
     } DISPATCH()
     } DISPATCH()
     case OP_COMPARE_NE:{
     case OP_COMPARE_NE:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         TOP() = VAR(py_ne(_0, _1));
         TOP() = VAR(py_ne(_0, _1));
     } DISPATCH()
     } DISPATCH()
     case OP_COMPARE_GT:{
     case OP_COMPARE_GT:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(>)
         PREDICT_INT_OP(>)
         TOP() = VAR(py_gt(_0, _1));
         TOP() = VAR(py_gt(_0, _1));
     } DISPATCH()
     } DISPATCH()
     case OP_COMPARE_GE:{
     case OP_COMPARE_GE:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(>=)
         PREDICT_INT_OP(>=)
         TOP() = VAR(py_ge(_0, _1));
         TOP() = VAR(py_ge(_0, _1));
     } DISPATCH()
     } DISPATCH()
     case OP_BITWISE_LSHIFT:{
     case OP_BITWISE_LSHIFT:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(<<)
         PREDICT_INT_OP(<<)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__lshift__);
         BINARY_OP_SPECIAL(__lshift__);
         if(TOP() == NotImplemented) BinaryOptError("<<", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("<<", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BITWISE_RSHIFT:{
     case OP_BITWISE_RSHIFT:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(>>)
         PREDICT_INT_OP(>>)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__rshift__);
         BINARY_OP_SPECIAL(__rshift__);
         if(TOP() == NotImplemented) BinaryOptError(">>", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError(">>", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BITWISE_AND:{
     case OP_BITWISE_AND:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(&)
         PREDICT_INT_OP(&)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__and__);
         BINARY_OP_SPECIAL(__and__);
         if(TOP() == NotImplemented) BinaryOptError("&", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("&", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BITWISE_OR:{
     case OP_BITWISE_OR:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(|)
         PREDICT_INT_OP(|)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__or__);
         BINARY_OP_SPECIAL(__or__);
         if(TOP() == NotImplemented) BinaryOptError("|", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("|", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BITWISE_XOR:{
     case OP_BITWISE_XOR:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         PREDICT_INT_OP(^)
         PREDICT_INT_OP(^)
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__xor__);
         BINARY_OP_SPECIAL(__xor__);
         if(TOP() == NotImplemented) BinaryOptError("^", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("^", _0, _1);
     } DISPATCH()
     } DISPATCH()
     case OP_BINARY_MATMUL:{
     case OP_BINARY_MATMUL:{
-        PyObject* _1 = POPX();
-        PyObject* _0 = TOP();
+        PyVar _1 = POPX();
+        PyVar _0 = TOP();
         const PyTypeInfo* _ti;
         const PyTypeInfo* _ti;
         BINARY_OP_SPECIAL(__matmul__);
         BINARY_OP_SPECIAL(__matmul__);
         if(TOP() == NotImplemented) BinaryOptError("@", _0, _1);
         if(TOP() == NotImplemented) BinaryOptError("@", _0, _1);
@@ -602,14 +602,14 @@ __NEXT_STEP:;
 #undef PREDICT_INT_OP
 #undef PREDICT_INT_OP
 
 
     case OP_IS_OP:{
     case OP_IS_OP:{
-        PyObject* _1 = POPX();    // rhs
-        PyObject* _0 = TOP();     // lhs
+        PyVar _1 = POPX();    // rhs
+        PyVar _0 = TOP();     // lhs
         TOP() = VAR(static_cast<bool>((_0==_1) ^ byte.arg));
         TOP() = VAR(static_cast<bool>((_0==_1) ^ byte.arg));
     } DISPATCH()
     } DISPATCH()
     case OP_CONTAINS_OP:{
     case OP_CONTAINS_OP:{
         // a in b -> b __contains__ a
         // a in b -> b __contains__ a
         auto _ti = _tp_info(TOP());
         auto _ti = _tp_info(TOP());
-        PyObject* _0;
+        PyVar _0;
         if(_ti->m__contains__){
         if(_ti->m__contains__){
             _0 = _ti->m__contains__(this, TOP(), SECOND());
             _0 = _ti->m__contains__(this, TOP(), SECOND());
         }else{
         }else{
@@ -662,7 +662,7 @@ __NEXT_STEP:;
     } DISPATCH()
     } DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_FSTRING_EVAL:{
     case OP_FSTRING_EVAL:{
-        PyObject* _0 = co->consts[byte.arg];
+        PyVar _0 = co->consts[byte.arg];
         std::string_view string = CAST(Str&, _0).sv();
         std::string_view string = CAST(Str&, _0).sv();
         auto it = __cached_codes.find(string);
         auto it = __cached_codes.find(string);
         CodeObject_ code;
         CodeObject_ code;
@@ -680,7 +680,7 @@ __NEXT_STEP:;
         DISPATCH()
         DISPATCH()
     case OP_CALL:{
     case OP_CALL:{
         if(heap._should_auto_collect()) heap._auto_collect();
         if(heap._should_auto_collect()) heap._auto_collect();
-        PyObject* _0 = vectorcall(
+        PyVar _0 = vectorcall(
             byte.arg & 0xFF,          // ARGC
             byte.arg & 0xFF,          // ARGC
             (byte.arg>>8) & 0xFF,     // KWARGC
             (byte.arg>>8) & 0xFF,     // KWARGC
             true
             true
@@ -693,15 +693,15 @@ __NEXT_STEP:;
     } DISPATCH()
     } DISPATCH()
     case OP_CALL_TP:{
     case OP_CALL_TP:{
         if(heap._should_auto_collect()) heap._auto_collect();
         if(heap._should_auto_collect()) heap._auto_collect();
-        PyObject* _0;
-        PyObject* _1;
-        PyObject* _2;
+        PyVar _0;
+        PyVar _1;
+        PyVar _2;
         // [callable, <self>, args: tuple, kwargs: dict | NULL]
         // [callable, <self>, args: tuple, kwargs: dict | NULL]
         if(byte.arg){
         if(byte.arg){
             _2 = POPX();
             _2 = POPX();
             _1 = POPX();
             _1 = POPX();
-            for(PyObject* obj: _CAST(Tuple&, _1)) PUSH(obj);
-            _CAST(Dict&, _2).apply([this](PyObject* k, PyObject* v){
+            for(PyVar obj: _CAST(Tuple&, _1)) PUSH(obj);
+            _CAST(Dict&, _2).apply([this](PyVar k, PyVar v){
                 PUSH(VAR(StrName(CAST(Str&, k)).index));
                 PUSH(VAR(StrName(CAST(Str&, k)).index));
                 PUSH(v);
                 PUSH(v);
             });
             });
@@ -713,7 +713,7 @@ __NEXT_STEP:;
         }else{
         }else{
             // no **kwargs
             // no **kwargs
             _1 = POPX();
             _1 = POPX();
-            for(PyObject* obj: _CAST(Tuple&, _1)) PUSH(obj);
+            for(PyVar obj: _CAST(Tuple&, _1)) PUSH(obj);
             _0 = vectorcall(
             _0 = vectorcall(
                 _CAST(Tuple&, _1).size(),   // ARGC
                 _CAST(Tuple&, _1).size(),   // ARGC
                 0,                          // KWARGC
                 0,                          // KWARGC
@@ -727,7 +727,7 @@ __NEXT_STEP:;
         PUSH(_0);
         PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_RETURN_VALUE:{
     case OP_RETURN_VALUE:{
-        PyObject* _0 = byte.arg == BC_NOARG ? POPX() : None;
+        PyVar _0 = byte.arg == BC_NOARG ? POPX() : None;
         __pop_frame();
         __pop_frame();
         if(frame == base_frame){       // [ frameBase<- ]
         if(frame == base_frame){       // [ frameBase<- ]
             return _0;
             return _0;
@@ -741,16 +741,16 @@ __NEXT_STEP:;
         return PY_OP_YIELD;
         return PY_OP_YIELD;
     /*****************************************/
     /*****************************************/
     case OP_LIST_APPEND:{
     case OP_LIST_APPEND:{
-        PyObject* _0 = POPX();
+        PyVar _0 = POPX();
         PK_OBJ_GET(List, SECOND()).push_back(_0);
         PK_OBJ_GET(List, SECOND()).push_back(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_DICT_ADD: {
     case OP_DICT_ADD: {
-        PyObject* _0 = POPX();
+        PyVar _0 = POPX();
         const Tuple& t = PK_OBJ_GET(Tuple, _0);
         const Tuple& t = PK_OBJ_GET(Tuple, _0);
         PK_OBJ_GET(Dict, SECOND()).set(t[0], t[1]);
         PK_OBJ_GET(Dict, SECOND()).set(t[0], t[1]);
     } DISPATCH()
     } DISPATCH()
     case OP_SET_ADD:{
     case OP_SET_ADD:{
-        PyObject* _0 = POPX();
+        PyVar _0 = POPX();
         call_method(SECOND(), pk_id_add, _0);
         call_method(SECOND(), pk_id_add, _0);
     } DISPATCH()
     } DISPATCH()
     /*****************************************/
     /*****************************************/
@@ -758,7 +758,7 @@ __NEXT_STEP:;
         TOP() = py_negate(TOP());
         TOP() = py_negate(TOP());
         DISPATCH()
         DISPATCH()
     case OP_UNARY_NOT:{
     case OP_UNARY_NOT:{
-        PyObject* _0 = TOP();
+        PyVar _0 = TOP();
         if(_0==True) TOP()=False;
         if(_0==True) TOP()=False;
         else if(_0==False) TOP()=True;
         else if(_0==False) TOP()=True;
         else TOP() = VAR(!py_bool(_0));
         else TOP() = VAR(!py_bool(_0));
@@ -767,7 +767,7 @@ __NEXT_STEP:;
         TOP() = VAR(StarWrapper(byte.arg, TOP()));
         TOP() = VAR(StarWrapper(byte.arg, TOP()));
         DISPATCH()
         DISPATCH()
     case OP_UNARY_INVERT:{
     case OP_UNARY_INVERT:{
-        PyObject* _0;
+        PyVar _0;
         auto _ti = _tp_info(TOP());
         auto _ti = _tp_info(TOP());
         if(_ti->m__invert__) _0 = _ti->m__invert__(this, TOP());
         if(_ti->m__invert__) _0 = _ti->m__invert__(this, TOP());
         else _0 = call_method(TOP(), __invert__);
         else _0 = call_method(TOP(), __invert__);
@@ -778,12 +778,12 @@ __NEXT_STEP:;
         TOP() = py_iter(TOP());
         TOP() = py_iter(TOP());
         DISPATCH()
         DISPATCH()
     case OP_FOR_ITER:{
     case OP_FOR_ITER:{
-        PyObject* _0 = py_next(TOP());
+        PyVar _0 = py_next(TOP());
         if(_0 == StopIteration) frame->loop_break(&s_data, co);
         if(_0 == StopIteration) frame->loop_break(&s_data, co);
         else PUSH(_0);
         else PUSH(_0);
     } DISPATCH()
     } DISPATCH()
     case OP_FOR_ITER_STORE_FAST:{
     case OP_FOR_ITER_STORE_FAST:{
-        PyObject* _0 = py_next(TOP());
+        PyVar _0 = py_next(TOP());
         if(_0 == StopIteration){
         if(_0 == StopIteration){
             frame->loop_break(&s_data, co);
             frame->loop_break(&s_data, co);
         }else{
         }else{
@@ -791,7 +791,7 @@ __NEXT_STEP:;
         }
         }
     } DISPATCH()
     } DISPATCH()
     case OP_FOR_ITER_STORE_GLOBAL:{
     case OP_FOR_ITER_STORE_GLOBAL:{
-        PyObject* _0 = py_next(TOP());
+        PyVar _0 = py_next(TOP());
         if(_0 == StopIteration){
         if(_0 == StopIteration){
             frame->loop_break(&s_data, co);
             frame->loop_break(&s_data, co);
         }else{
         }else{
@@ -799,7 +799,7 @@ __NEXT_STEP:;
         }
         }
     } DISPATCH()
     } DISPATCH()
     case OP_FOR_ITER_YIELD_VALUE:{
     case OP_FOR_ITER_YIELD_VALUE:{
-        PyObject* _0 = py_next(TOP());
+        PyVar _0 = py_next(TOP());
         if(_0 == StopIteration){
         if(_0 == StopIteration){
             frame->loop_break(&s_data, co);
             frame->loop_break(&s_data, co);
         }else{
         }else{
@@ -808,7 +808,7 @@ __NEXT_STEP:;
         }
         }
     } DISPATCH()
     } DISPATCH()
     case OP_FOR_ITER_UNPACK:{
     case OP_FOR_ITER_UNPACK:{
-        PyObject* _0 = TOP();
+        PyVar _0 = TOP();
         const PyTypeInfo* _ti = _tp_info(_0);
         const PyTypeInfo* _ti = _tp_info(_0);
         if(_ti->m__next__){
         if(_ti->m__next__){
             unsigned n = _ti->m__next__(this, _0);
             unsigned n = _ti->m__next__(this, _0);
@@ -837,17 +837,17 @@ __NEXT_STEP:;
     } DISPATCH()
     } DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_IMPORT_PATH:{
     case OP_IMPORT_PATH:{
-        PyObject* _0 = co->consts[byte.arg];
+        PyVar _0 = co->consts[byte.arg];
         PUSH(py_import(CAST(Str&, _0)));
         PUSH(py_import(CAST(Str&, _0)));
     } DISPATCH()
     } DISPATCH()
     case OP_POP_IMPORT_STAR: {
     case OP_POP_IMPORT_STAR: {
-        PyObject* _0 = POPX();        // pop the module
-        PyObject* _1 = _0->attr().try_get(__all__);
+        PyVar _0 = POPX();        // pop the module
+        PyVar _1 = _0->attr().try_get(__all__);
         StrName _name;
         StrName _name;
         if(_1 != nullptr){
         if(_1 != nullptr){
-            for(PyObject* key: CAST(List&, _1)){
+            for(PyVar key: CAST(List&, _1)){
                 _name = StrName::get(CAST(Str&, key).sv());
                 _name = StrName::get(CAST(Str&, key).sv());
-                PyObject* value = _0->attr().try_get_likely_found(_name);
+                PyVar value = _0->attr().try_get_likely_found(_name);
                 if(value == nullptr){
                 if(value == nullptr){
                     ImportError(_S("cannot import name ", _name.escape()));
                     ImportError(_S("cannot import name ", _name.escape()));
                 }else{
                 }else{
@@ -868,9 +868,9 @@ __NEXT_STEP:;
     } DISPATCH()
     } DISPATCH()
     case OP_UNPACK_EX: {
     case OP_UNPACK_EX: {
         auto _lock = heap.gc_scope_lock();  // lock the gc via RAII!!
         auto _lock = heap.gc_scope_lock();  // lock the gc via RAII!!
-        PyObject* _0 = py_iter(POPX());
+        PyVar _0 = py_iter(POPX());
         const PyTypeInfo* _ti = _tp_info(_0);
         const PyTypeInfo* _ti = _tp_info(_0);
-        PyObject* _1;
+        PyVar _1;
         for(int i=0; i<byte.arg; i++){
         for(int i=0; i<byte.arg; i++){
             _1 = _py_next(_ti, _0);
             _1 = _py_next(_ti, _0);
             if(_1 == StopIteration) ValueError("not enough values to unpack");
             if(_1 == StopIteration) ValueError("not enough values to unpack");
@@ -887,7 +887,7 @@ __NEXT_STEP:;
     /*****************************************/
     /*****************************************/
     case OP_BEGIN_CLASS:{
     case OP_BEGIN_CLASS:{
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject* _0 = POPX();   // super
+        PyVar _0 = POPX();   // super
         if(_0 == None) _0 = _t(tp_object);
         if(_0 == None) _0 = _t(tp_object);
         check_type(_0, tp_type);
         check_type(_0, tp_type);
         __curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0));
         __curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0));
@@ -907,7 +907,7 @@ __NEXT_STEP:;
     case OP_STORE_CLASS_ATTR:{
     case OP_STORE_CLASS_ATTR:{
         PK_ASSERT(__curr_class != nullptr);
         PK_ASSERT(__curr_class != nullptr);
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject* _0 = POPX();
+        PyVar _0 = POPX();
         if(is_type(_0, tp_function)){
         if(is_type(_0, tp_function)){
             PK_OBJ_GET(Function, _0)._class = __curr_class;
             PK_OBJ_GET(Function, _0)._class = __curr_class;
         }
         }
@@ -935,9 +935,9 @@ __NEXT_STEP:;
         DISPATCH()
         DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_EXCEPTION_MATCH: {
     case OP_EXCEPTION_MATCH: {
-        PyObject* assumed_type = POPX();
+        PyVar assumed_type = POPX();
         check_type(assumed_type, tp_type);
         check_type(assumed_type, tp_type);
-        PyObject* e_obj = TOP();
+        PyVar e_obj = TOP();
         bool ok = isinstance(e_obj, PK_OBJ_GET(Type, assumed_type));
         bool ok = isinstance(e_obj, PK_OBJ_GET(Type, assumed_type));
         PUSH(VAR(ok));
         PUSH(VAR(ok));
     } DISPATCH()
     } DISPATCH()
@@ -963,30 +963,30 @@ __NEXT_STEP:;
     case OP_POP_EXCEPTION: __last_exception = POPX(); DISPATCH()
     case OP_POP_EXCEPTION: __last_exception = POPX(); DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_FORMAT_STRING: {
     case OP_FORMAT_STRING: {
-        PyObject* _0 = POPX();
+        PyVar _0 = POPX();
         const Str& spec = CAST(Str&, co->consts[byte.arg]);
         const Str& spec = CAST(Str&, co->consts[byte.arg]);
         PUSH(__format_object(_0, spec));
         PUSH(__format_object(_0, spec));
     } DISPATCH()
     } DISPATCH()
     /*****************************************/
     /*****************************************/
     case OP_INC_FAST:{
     case OP_INC_FAST:{
-        PyObject** p = &frame->_locals[byte.arg];
+        PyVar* p = &frame->_locals[byte.arg];
         if(*p == PY_NULL) vm->NameError(co->varnames[byte.arg]);
         if(*p == PY_NULL) vm->NameError(co->varnames[byte.arg]);
         *p = VAR(CAST(i64, *p) + 1);
         *p = VAR(CAST(i64, *p) + 1);
     } DISPATCH()
     } DISPATCH()
     case OP_DEC_FAST:{
     case OP_DEC_FAST:{
-        PyObject** p = &frame->_locals[byte.arg];
+        PyVar* p = &frame->_locals[byte.arg];
         if(*p == PY_NULL) vm->NameError(co->varnames[byte.arg]);
         if(*p == PY_NULL) vm->NameError(co->varnames[byte.arg]);
         *p = VAR(CAST(i64, *p) - 1);
         *p = VAR(CAST(i64, *p) - 1);
     } DISPATCH()
     } DISPATCH()
     case OP_INC_GLOBAL:{
     case OP_INC_GLOBAL:{
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject** p = frame->f_globals().try_get_2_likely_found(_name);
+        PyVar* p = frame->f_globals().try_get_2_likely_found(_name);
         if(p == nullptr) vm->NameError(_name);
         if(p == nullptr) vm->NameError(_name);
         *p = VAR(CAST(i64, *p) + 1);
         *p = VAR(CAST(i64, *p) + 1);
     } DISPATCH()
     } DISPATCH()
     case OP_DEC_GLOBAL:{
     case OP_DEC_GLOBAL:{
         StrName _name(byte.arg);
         StrName _name(byte.arg);
-        PyObject** p = frame->f_globals().try_get_2_likely_found(_name);
+        PyVar* p = frame->f_globals().try_get_2_likely_found(_name);
         if(p == nullptr) vm->NameError(_name);
         if(p == nullptr) vm->NameError(_name);
         *p = VAR(CAST(i64, *p) - 1);
         *p = VAR(CAST(i64, *p) - 1);
     } DISPATCH()
     } DISPATCH()
@@ -998,7 +998,7 @@ __NEXT_STEP:;
         }catch(HandledException){
         }catch(HandledException){
             continue;
             continue;
         }catch(UnhandledException){
         }catch(UnhandledException){
-            PyObject* e_obj = POPX();
+            PyVar e_obj = POPX();
             Exception& _e = PK_OBJ_GET(Exception, e_obj);
             Exception& _e = PK_OBJ_GET(Exception, e_obj);
             bool is_base_frame_to_be_popped = frame == base_frame;
             bool is_base_frame_to_be_popped = frame == base_frame;
             __pop_frame();
             __pop_frame();

+ 16 - 16
src/cffi.cpp

@@ -2,25 +2,25 @@
 
 
 namespace pkpy{
 namespace pkpy{
 
 
-    void VoidP::_register(VM* vm, PyObject* mod, PyObject* type){
+    void VoidP::_register(VM* vm, PyVar mod, PyVar type){
         vm->bind_func(type, __new__, 2, [](VM* vm, ArgsView args){
         vm->bind_func(type, __new__, 2, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             Type cls = PK_OBJ_GET(Type, args[0]);
             i64 addr = CAST(i64, args[1]);
             i64 addr = CAST(i64, args[1]);
             return vm->heap.gcnew<VoidP>(cls, reinterpret_cast<void*>(addr));
             return vm->heap.gcnew<VoidP>(cls, reinterpret_cast<void*>(addr));
         });
         });
 
 
-        vm->bind__hash__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj){
+        vm->bind__hash__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj){
             VoidP& self = PK_OBJ_GET(VoidP, obj);
             VoidP& self = PK_OBJ_GET(VoidP, obj);
             return reinterpret_cast<i64>(self.ptr);
             return reinterpret_cast<i64>(self.ptr);
         });
         });
 
 
-        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj) -> Str{
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj) -> Str{
             VoidP& self = PK_OBJ_GET(VoidP, obj);
             VoidP& self = PK_OBJ_GET(VoidP, obj);
             return _S("<void* at ", self.hex(), ">");
             return _S("<void* at ", self.hex(), ">");
         });
         });
 
 
 #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, PyVar lhs, PyVar rhs){        \
             if(!vm->isinstance(rhs, vm->_tp_user<VoidP>())) 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;                                              \
@@ -37,7 +37,7 @@ namespace pkpy{
     }
     }
 
 
 
 
-    void Struct::_register(VM* vm, PyObject* mod, PyObject* type){
+    void Struct::_register(VM* vm, PyVar mod, PyVar type){
         vm->bind_func(type, __new__, 2, [](VM* vm, ArgsView args){
         vm->bind_func(type, __new__, 2, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             Type cls = PK_OBJ_GET(Type, args[0]);
             int size = CAST(int, args[1]);
             int size = CAST(int, args[1]);
@@ -72,7 +72,7 @@ namespace pkpy{
             return vm->new_user_object<Struct>(std::move(buffer));
             return vm->new_user_object<Struct>(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, PyVar obj){
             Struct& self = _CAST(Struct&, obj);
             Struct& self = _CAST(Struct&, obj);
             SStream ss;
             SStream ss;
             ss << "<struct object of " << self.size << " bytes>";
             ss << "<struct object of " << self.size << " bytes>";
@@ -94,7 +94,7 @@ namespace pkpy{
             return vm->heap.gcnew<Struct>(vm->_tp(args[0]), self);
             return vm->heap.gcnew<Struct>(vm->_tp(args[0]), self);
         });
         });
 
 
-        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* lhs, PyObject* rhs){
+        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar lhs, PyVar rhs){
             Struct& self = _CAST(Struct&, lhs);
             Struct& self = _CAST(Struct&, lhs);
             if(!vm->is_user_type<Struct>(rhs)) return vm->NotImplemented;
             if(!vm->is_user_type<Struct>(rhs)) return vm->NotImplemented;
             Struct& other = _CAST(Struct&, rhs);
             Struct& other = _CAST(Struct&, rhs);
@@ -134,7 +134,7 @@ namespace pkpy{
     }
     }
 
 
 void add_module_c(VM* vm){
 void add_module_c(VM* vm){
-    PyObject* mod = vm->new_module("c");
+    PyVar mod = vm->new_module("c");
     
     
     vm->bind_func(mod, "malloc", 1, [](VM* vm, ArgsView args){
     vm->bind_func(mod, "malloc", 1, [](VM* vm, ArgsView args){
         i64 size = CAST(i64, args[0]);
         i64 size = CAST(i64, args[0]);
@@ -187,7 +187,7 @@ void add_module_c(VM* vm){
         return vm->heap.gcnew<VoidP>(args[0]->type, value);
         return vm->heap.gcnew<VoidP>(args[0]->type, value);
     });
     });
 
 
-    PyObject* type;
+    PyVar type;
     Type type_t;
     Type type_t;
 
 
 #define BIND_PRIMITIVE(T, CNAME) \
 #define BIND_PRIMITIVE(T, CNAME) \
@@ -210,31 +210,31 @@ void add_module_c(VM* vm){
         *target = val;                                                  \
         *target = val;                                                  \
         return vm->None;                                                \
         return vm->None;                                                \
     });                                                                 \
     });                                                                 \
-    vm->bind__getitem__(type_t, [](VM* vm, PyObject* obj, PyObject* index){  \
+    vm->bind__getitem__(type_t, [](VM* vm, PyVar obj, PyVar index){  \
         VoidP& voidp = PK_OBJ_GET(VoidP, obj);                               \
         VoidP& voidp = PK_OBJ_GET(VoidP, obj);                               \
         i64 offset = CAST(i64, index);                                  \
         i64 offset = CAST(i64, index);                                  \
         T* target = (T*)voidp.ptr;                                      \
         T* target = (T*)voidp.ptr;                                      \
         return VAR(target[offset]);                                     \
         return VAR(target[offset]);                                     \
     });                                                                 \
     });                                                                 \
-    vm->bind__setitem__(type_t, [](VM* vm, PyObject* obj, PyObject* index, PyObject* value){   \
+    vm->bind__setitem__(type_t, [](VM* vm, PyVar obj, PyVar index, PyVar value){   \
         VoidP& voidp = PK_OBJ_GET(VoidP, obj);                          \
         VoidP& voidp = PK_OBJ_GET(VoidP, obj);                          \
         i64 offset = CAST(i64, index);                                  \
         i64 offset = CAST(i64, index);                                  \
         T* target = (T*)voidp.ptr;                                      \
         T* target = (T*)voidp.ptr;                                      \
         target[offset] = CAST(T, value);                                \
         target[offset] = CAST(T, value);                                \
     });                                                                 \
     });                                                                 \
-    vm->bind__add__(type_t, [](VM* vm, PyObject* lhs, PyObject* rhs){   \
+    vm->bind__add__(type_t, [](VM* vm, PyVar lhs, PyVar rhs){   \
         VoidP& voidp = PK_OBJ_GET(VoidP, lhs);                          \
         VoidP& voidp = PK_OBJ_GET(VoidP, lhs);                          \
         i64 offset = CAST(i64, rhs);                                    \
         i64 offset = CAST(i64, rhs);                                    \
         T* target = (T*)voidp.ptr;                                      \
         T* target = (T*)voidp.ptr;                                      \
         return vm->heap.gcnew<VoidP>(lhs->type, target + offset);       \
         return vm->heap.gcnew<VoidP>(lhs->type, target + offset);       \
     });                                                                 \
     });                                                                 \
-    vm->bind__sub__(type_t, [](VM* vm, PyObject* lhs, PyObject* rhs){   \
+    vm->bind__sub__(type_t, [](VM* vm, PyVar lhs, PyVar rhs){   \
         VoidP& voidp = PK_OBJ_GET(VoidP, lhs);                          \
         VoidP& voidp = PK_OBJ_GET(VoidP, lhs);                          \
         i64 offset = CAST(i64, rhs);                                    \
         i64 offset = CAST(i64, rhs);                                    \
         T* target = (T*)voidp.ptr;                                      \
         T* target = (T*)voidp.ptr;                                      \
         return vm->heap.gcnew<VoidP>(lhs->type, target - offset);       \
         return vm->heap.gcnew<VoidP>(lhs->type, target - offset);       \
     });                                                                 \
     });                                                                 \
-    vm->bind__repr__(type_t, [](VM* vm, PyObject* obj) -> Str{          \
+    vm->bind__repr__(type_t, [](VM* vm, PyVar obj) -> Str{          \
         VoidP& self = _CAST(VoidP&, obj);                               \
         VoidP& self = _CAST(VoidP&, obj);                               \
         return _S("<", CNAME, "* at ", self.hex(), ">");                \
         return _S("<", CNAME, "* at ", self.hex(), ">");                \
     });                                                                 \
     });                                                                 \
@@ -255,7 +255,7 @@ void add_module_c(VM* vm){
 
 
 #undef BIND_PRIMITIVE
 #undef BIND_PRIMITIVE
 
 
-    PyObject* char_p_t = mod->attr("char_p");
+    PyVar char_p_t = mod->attr("char_p");
     vm->bind(char_p_t, "read_string(self) -> str", [](VM* vm, ArgsView args){
     vm->bind(char_p_t, "read_string(self) -> str", [](VM* vm, ArgsView args){
         VoidP& voidp = PK_OBJ_GET(VoidP, args[0]);
         VoidP& voidp = PK_OBJ_GET(VoidP, args[0]);
         const char* target = (const char*)voidp.ptr;
         const char* target = (const char*)voidp.ptr;
@@ -272,7 +272,7 @@ void add_module_c(VM* vm){
     });
     });
 }
 }
 
 
-PyObject* from_void_p(VM* vm, void* p){
+PyVar from_void_p(VM* vm, void* p){
     return vm->new_user_object<VoidP>(p);
     return vm->new_user_object<VoidP>(p);
 }
 }
 
 

+ 4 - 4
src/codeobject.cpp

@@ -8,7 +8,7 @@ namespace pkpy{
         }
         }
 
 
     void CodeObject::_gc_mark() const {
     void CodeObject::_gc_mark() const {
-        for(PyObject* v : consts) PK_OBJ_MARK(v);
+        for(PyVar v : consts) PK_OBJ_MARK(v);
         for(auto& decl: func_decls) decl->_gc_mark();
         for(auto& decl: func_decls) decl->_gc_mark();
     }
     }
 
 
@@ -17,7 +17,7 @@ namespace pkpy{
         void _obj_gc_mark() override {}
         void _obj_gc_mark() override {}
     };
     };
 
 
-    PyObject* const PY_NULL = new PySignalObject();
-    PyObject* const PY_OP_CALL = new PySignalObject();
-    PyObject* const PY_OP_YIELD = new PySignalObject();
+    PyVar const PY_NULL = new PySignalObject();
+    PyVar const PY_OP_CALL = new PySignalObject();
+    PyVar const PY_OP_YIELD = new PySignalObject();
 }   // namespace pkpy
 }   // namespace pkpy

+ 9 - 9
src/collections.cpp

@@ -67,7 +67,7 @@ namespace pkpy
                  });
                  });
         // gets the item at the given index, if index is negative, it will be treated as index + len(deque)
         // gets the item at the given index, if index is negative, it will be treated as index + len(deque)
         // if the index is out of range, IndexError will be thrown --> required for [] operator
         // if the index is out of range, IndexError will be thrown --> required for [] operator
-        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1)
+        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM *vm, PyVar _0, PyVar _1)
         {
         {
             PyDeque &self = _CAST(PyDeque &, _0);
             PyDeque &self = _CAST(PyDeque &, _0);
             i64 index = CAST(i64, _1);
             i64 index = CAST(i64, _1);
@@ -76,7 +76,7 @@ namespace pkpy
         });
         });
         // sets the item at the given index, if index is negative, it will be treated as index + len(deque)
         // sets the item at the given index, if index is negative, it will be treated as index + len(deque)
         // if the index is out of range, IndexError will be thrown --> required for [] operator
         // if the index is out of range, IndexError will be thrown --> required for [] operator
-        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1, PyObject* _2)
+        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM *vm, PyVar _0, PyVar _1, PyVar _2)
         {
         {
             PyDeque &self = _CAST(PyDeque&, _0);
             PyDeque &self = _CAST(PyDeque&, _0);
             i64 index = CAST(i64, _1);
             i64 index = CAST(i64, _1);
@@ -85,7 +85,7 @@ namespace pkpy
         });
         });
         // erases the item at the given index, if index is negative, it will be treated as index + len(deque)
         // erases the item at the given index, if index is negative, it will be treated as index + len(deque)
         // if the index is out of range, IndexError will be thrown --> required for [] operator
         // if the index is out of range, IndexError will be thrown --> required for [] operator
-        vm->bind__delitem__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1)
+        vm->bind__delitem__(PK_OBJ_GET(Type, type), [](VM *vm, PyVar _0, PyVar _1)
         {
         {
             PyDeque &self = _CAST(PyDeque&, _0);
             PyDeque &self = _CAST(PyDeque&, _0);
             i64 index = CAST(i64, _1);
             i64 index = CAST(i64, _1);
@@ -93,19 +93,19 @@ namespace pkpy
             self.dequeItems.erase(self.dequeItems.begin() + index);
             self.dequeItems.erase(self.dequeItems.begin() + index);
         });
         });
 
 
-        vm->bind__len__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0)
+        vm->bind__len__(PK_OBJ_GET(Type, type), [](VM *vm, PyVar _0)
         {
         {
             PyDeque &self = _CAST(PyDeque&, _0);
             PyDeque &self = _CAST(PyDeque&, _0);
             return (i64)self.dequeItems.size();
             return (i64)self.dequeItems.size();
         });
         });
 
 
-        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0)
+        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM *vm, PyVar _0)
         {
         {
             PyDeque &self = _CAST(PyDeque &, _0);
             PyDeque &self = _CAST(PyDeque &, _0);
             return vm->new_user_object<PyDequeIter>(_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) -> Str
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM *vm, PyVar _0) -> Str
         {
         {
             if(vm->_repr_recursion_set.count(_0)) return "[...]";
             if(vm->_repr_recursion_set.count(_0)) return "[...]";
             const PyDeque &self = _CAST(PyDeque&, _0);
             const PyDeque &self = _CAST(PyDeque&, _0);
@@ -123,7 +123,7 @@ namespace pkpy
         });
         });
 
 
         // enables comparison between two deques, == and != are supported
         // enables comparison between two deques, == and != are supported
-        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM *vm, PyObject* _0, PyObject* _1)
+        vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM *vm, PyVar _0, PyVar _1)
         {
         {
             const PyDeque &self = _CAST(PyDeque&, _0);
             const PyDeque &self = _CAST(PyDeque&, _0);
             if(!vm->is_user_type<PyDeque>(_0)) return vm->NotImplemented;
             if(!vm->is_user_type<PyDeque>(_0)) return vm->NotImplemented;
@@ -444,7 +444,7 @@ namespace pkpy
     /// @param back if true, pop from the back of the deque
     /// @param back if true, pop from the back of the deque
     /// @param item if front and back is not set, remove the first occurrence of item from the deque
     /// @param item if front and back is not set, remove the first occurrence of item from the deque
     /// @param vm is needed for the py_eq
     /// @param vm is needed for the py_eq
-    /// @return PyObject* if front or back is set, this is a pop operation and we return a PyObject*, if front and back are not set, this is a remove operation and we return the removed item or nullptr
+    /// @return PyVar if front or back is set, this is a pop operation and we return a PyVar, if front and back are not set, this is a remove operation and we return the removed item or nullptr
     PyObject *PyDeque::popObj(bool front, bool back, PyObject *item, VM *vm)
     PyObject *PyDeque::popObj(bool front, bool back, PyObject *item, VM *vm)
     {
     {
         // error handling
         // error handling
@@ -452,7 +452,7 @@ namespace pkpy
             throw std::runtime_error("both front and back are set"); // this should never happen
             throw std::runtime_error("both front and back are set"); // this should never happen
         if (front || back)
         if (front || back)
         {
         {
-            // front or back is set, we don't care about item, this is a pop operation and we return a PyObject*
+            // front or back is set, we don't care about item, this is a pop operation and we return a PyVar
             if (this->dequeItems.empty())
             if (this->dequeItems.empty())
                 throw std::runtime_error("pop from an empty deque"); // shouldn't happen
                 throw std::runtime_error("pop from an empty deque"); // shouldn't happen
             PyObject *obj;
             PyObject *obj;

+ 7 - 7
src/compiler.cpp

@@ -1124,7 +1124,7 @@ __EAT_DOTS_END:
                     break;
                     break;
                 case 2: {
                 case 2: {
                     consume(TK("="));
                     consume(TK("="));
-                    PyObject* value = read_literal();
+                    PyVar value = read_literal();
                     if(value == nullptr){
                     if(value == nullptr){
                         SyntaxError(Str("default argument must be a literal"));
                         SyntaxError(Str("default argument must be a literal"));
                     }
                     }
@@ -1153,7 +1153,7 @@ __EAT_DOTS_END:
 
 
         decl->docstring = nullptr;
         decl->docstring = nullptr;
         if(decl->code->codes.size()>=2 && decl->code->codes[0].op == OP_LOAD_CONST && decl->code->codes[1].op == OP_POP_TOP){
         if(decl->code->codes.size()>=2 && decl->code->codes[0].op == OP_LOAD_CONST && decl->code->codes[1].op == OP_POP_TOP){
-            PyObject* c = decl->code->consts[decl->code->codes[0].arg];
+            PyVar c = decl->code->consts[decl->code->codes[0].arg];
             if(is_type(c, vm->tp_str)){
             if(is_type(c, vm->tp_str)){
                 decl->code->codes[0].op = OP_NO_OP;
                 decl->code->codes[0].op = OP_NO_OP;
                 decl->code->codes[1].op = OP_NO_OP;
                 decl->code->codes[1].op = OP_NO_OP;
@@ -1173,8 +1173,8 @@ __EAT_DOTS_END:
         }
         }
     }
     }
 
 
-    PyObject* Compiler::to_object(const TokenValue& value){
-        PyObject* obj = nullptr;
+    PyVar Compiler::to_object(const TokenValue& value){
+        PyVar obj = nullptr;
         if(std::holds_alternative<i64>(value)){
         if(std::holds_alternative<i64>(value)){
             obj = VAR(std::get<i64>(value));
             obj = VAR(std::get<i64>(value));
         }
         }
@@ -1188,12 +1188,12 @@ __EAT_DOTS_END:
         return obj;
         return obj;
     }
     }
 
 
-    PyObject* Compiler::read_literal(){
+    PyVar Compiler::read_literal(){
         advance();
         advance();
         switch(prev().type){
         switch(prev().type){
             case TK("-"): {
             case TK("-"): {
                 consume(TK("@num"));
                 consume(TK("@num"));
-                PyObject* val = to_object(prev().value);
+                PyVar val = to_object(prev().value);
                 return vm->py_negate(val);
                 return vm->py_negate(val);
             }
             }
             case TK("@num"): return to_object(prev().value);
             case TK("@num"): return to_object(prev().value);
@@ -1373,7 +1373,7 @@ __EAT_DOTS_END:
 
 
     // TODO: refactor this
     // TODO: refactor this
     void Lexer::throw_err(StrName type, Str msg, int lineno, const char* cursor){
     void Lexer::throw_err(StrName type, Str msg, int lineno, const char* cursor){
-        PyObject* e_obj = vm->call(vm->builtins->attr(type), VAR(msg));
+        PyVar e_obj = vm->call(vm->builtins->attr(type), VAR(msg));
         Exception& e = PK_OBJ_GET(Exception, e_obj);
         Exception& e = PK_OBJ_GET(Exception, e_obj);
         e.st_push(src, lineno, cursor, "");
         e.st_push(src, lineno, cursor, "");
         throw e;
         throw e;

+ 3 - 3
src/csv.cpp

@@ -3,7 +3,7 @@
 namespace pkpy{
 namespace pkpy{
 
 
 void add_module_csv(VM *vm){
 void add_module_csv(VM *vm){
-    PyObject* mod = vm->new_module("csv");
+    PyVar mod = vm->new_module("csv");
 
 
     vm->bind(mod, "reader(csvfile: list[str]) -> list[list]", [](VM* vm, ArgsView args){
     vm->bind(mod, "reader(csvfile: list[str]) -> list[list]", [](VM* vm, ArgsView args){
         const List& csvfile = CAST(List&, args[0]);
         const List& csvfile = CAST(List&, args[0]);
@@ -67,8 +67,8 @@ __NEXT_LINE:
     });
     });
 
 
     vm->bind(mod, "DictReader(csvfile: list[str]) -> list[dict]", [](VM* vm, ArgsView args){
     vm->bind(mod, "DictReader(csvfile: list[str]) -> list[dict]", [](VM* vm, ArgsView args){
-        PyObject* csv_reader = vm->_modules["csv"]->attr("reader");
-        PyObject* ret_obj = vm->call(csv_reader, args[0]);
+        PyVar csv_reader = vm->_modules["csv"]->attr("reader");
+        PyVar ret_obj = vm->call(csv_reader, args[0]);
         const List& ret = CAST(List&, ret_obj);
         const List& ret = CAST(List&, ret_obj);
         if(ret.size() == 0){
         if(ret.size() == 0){
             vm->ValueError("empty csvfile");
             vm->ValueError("empty csvfile");

+ 7 - 7
src/dataclasses.cpp

@@ -4,11 +4,11 @@ namespace pkpy{
 
 
 static void patch__init__(VM* vm, Type cls){
 static void patch__init__(VM* vm, Type cls){
     vm->bind(vm->_t(cls), "__init__(self, *args, **kwargs)", [](VM* vm, ArgsView _view){
     vm->bind(vm->_t(cls), "__init__(self, *args, **kwargs)", [](VM* vm, ArgsView _view){
-        PyObject* self = _view[0];
+        PyVar self = _view[0];
         const Tuple& args = CAST(Tuple&, _view[1]);
         const Tuple& args = CAST(Tuple&, _view[1]);
         const Dict& kwargs_ = CAST(Dict&, _view[2]);
         const Dict& kwargs_ = CAST(Dict&, _view[2]);
         NameDict kwargs;
         NameDict kwargs;
-        kwargs_.apply([&](PyObject* k, PyObject* v){
+        kwargs_.apply([&](PyVar k, PyVar v){
             kwargs.set(CAST(Str&, k), v);
             kwargs.set(CAST(Str&, k), v);
         });
         });
 
 
@@ -45,7 +45,7 @@ static void patch__init__(VM* vm, Type cls){
 }
 }
 
 
 static void patch__repr__(VM* vm, Type cls){
 static void patch__repr__(VM* vm, Type cls){
-    vm->bind__repr__(cls, [](VM* vm, PyObject* _0) -> Str{
+    vm->bind__repr__(cls, [](VM* vm, PyVar _0) -> Str{
         const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
         const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
         const auto& fields = cls_info->annotated_fields;
         const auto& fields = cls_info->annotated_fields;
         const NameDict& obj_d = _0->attr();
         const NameDict& obj_d = _0->attr();
@@ -63,13 +63,13 @@ static void patch__repr__(VM* vm, Type cls){
 }
 }
 
 
 static void patch__eq__(VM* vm, Type cls){
 static void patch__eq__(VM* vm, Type cls){
-    vm->bind__eq__(cls, [](VM* vm, PyObject* _0, PyObject* _1){
+    vm->bind__eq__(cls, [](VM* vm, PyVar _0, PyVar _1){
         if(vm->_tp(_0) != vm->_tp(_1)) return vm->NotImplemented;
         if(vm->_tp(_0) != vm->_tp(_1)) return vm->NotImplemented;
         const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
         const PyTypeInfo* cls_info = &vm->_all_types[vm->_tp(_0)];
         const auto& fields = cls_info->annotated_fields;
         const auto& fields = cls_info->annotated_fields;
         for(StrName field: fields){
         for(StrName field: fields){
-            PyObject* lhs = _0->attr(field);
-            PyObject* rhs = _1->attr(field);
+            PyVar lhs = _0->attr(field);
+            PyVar rhs = _1->attr(field);
             if(vm->py_ne(lhs, rhs)) return vm->False;
             if(vm->py_ne(lhs, rhs)) return vm->False;
         }
         }
         return vm->True;
         return vm->True;
@@ -77,7 +77,7 @@ static void patch__eq__(VM* vm, Type cls){
 }
 }
 
 
 void add_module_dataclasses(VM* vm){
 void add_module_dataclasses(VM* vm){
-    PyObject* mod = vm->new_module("dataclasses");
+    PyVar mod = vm->new_module("dataclasses");
 
 
     vm->bind_func(mod, "dataclass", 1, [](VM* vm, ArgsView args){
     vm->bind_func(mod, "dataclass", 1, [](VM* vm, ArgsView args){
         vm->check_type(args[0], VM::tp_type);
         vm->check_type(args[0], VM::tp_type);

+ 6 - 6
src/dict.cpp

@@ -39,7 +39,7 @@ namespace pkpy{
         memcpy(_nodes, other._nodes, _capacity * sizeof(ItemNode));
         memcpy(_nodes, other._nodes, _capacity * sizeof(ItemNode));
     }
     }
 
 
-    void Dict::set(PyObject* key, PyObject* val){
+    void Dict::set(PyVar key, PyVar val){
         // do possible rehash
         // do possible rehash
         if(_size+1 > _critical_size) _rehash();
         if(_size+1 > _critical_size) _rehash();
         bool ok; int i;
         bool ok; int i;
@@ -89,20 +89,20 @@ namespace pkpy{
     }
     }
 
 
 
 
-    PyObject* Dict::try_get(PyObject* key) const{
+    PyVar Dict::try_get(PyVar key) const{
         bool ok; int i;
         bool ok; int i;
         _probe_0(key, ok, i);
         _probe_0(key, ok, i);
         if(!ok) return nullptr;
         if(!ok) return nullptr;
         return _items[i].second;
         return _items[i].second;
     }
     }
 
 
-    bool Dict::contains(PyObject* key) const{
+    bool Dict::contains(PyVar key) const{
         bool ok; int i;
         bool ok; int i;
         _probe_0(key, ok, i);
         _probe_0(key, ok, i);
         return ok;
         return ok;
     }
     }
 
 
-    bool Dict::erase(PyObject* key){
+    bool Dict::erase(PyVar key){
         bool ok; int i;
         bool ok; int i;
         _probe_0(key, ok, i);
         _probe_0(key, ok, i);
         if(!ok) return false;
         if(!ok) return false;
@@ -131,7 +131,7 @@ namespace pkpy{
     }
     }
 
 
     void Dict::update(const Dict& other){
     void Dict::update(const Dict& other){
-        other.apply([&](PyObject* k, PyObject* v){ set(k, v); });
+        other.apply([&](PyVar k, PyVar v){ set(k, v); });
     }
     }
 
 
     Tuple Dict::keys() const{
     Tuple Dict::keys() const{
@@ -173,7 +173,7 @@ namespace pkpy{
     }
     }
 
 
     void Dict::_gc_mark() const{
     void Dict::_gc_mark() const{
-        apply([](PyObject* k, PyObject* v){
+        apply([](PyVar k, PyVar v){
             PK_OBJ_MARK(k);
             PK_OBJ_MARK(k);
             PK_OBJ_MARK(v);
             PK_OBJ_MARK(v);
         });
         });

+ 1 - 1
src/easing.cpp

@@ -206,7 +206,7 @@ static double easeInOutBounce( double x ) {
 }
 }
 
 
 void add_module_easing(VM* vm){
 void add_module_easing(VM* vm){
-    PyObject* mod = vm->new_module("easing");
+    PyVar mod = vm->new_module("easing");
 
 
 #define EASE(name)  \
 #define EASE(name)  \
     vm->bind_func(mod, #name, 1, [](VM* vm, ArgsView args){  \
     vm->bind_func(mod, #name, 1, [](VM* vm, ArgsView args){  \

+ 1 - 1
src/expr.cpp

@@ -131,7 +131,7 @@ namespace pkpy{
         }
         }
     }
     }
 
 
-    int CodeEmitContext::add_const(PyObject* v){
+    int CodeEmitContext::add_const(PyVar v){
         if(is_type(v, vm->tp_str)){
         if(is_type(v, vm->tp_str)){
             // warning: should use add_const_string() instead
             // warning: should use add_const_string() instead
             return add_const_string(PK_OBJ_GET(Str, v).sv());
             return add_const_string(PK_OBJ_GET(Str, v).sv());

+ 4 - 4
src/frame.cpp

@@ -1,7 +1,7 @@
 #include "pocketpy/frame.h"
 #include "pocketpy/frame.h"
 
 
 namespace pkpy{
 namespace pkpy{
-    PyObject** FastLocals::try_get_name(StrName name){
+    PyVar* FastLocals::try_get_name(StrName name){
         int index = co->varnames_inv.try_get(name);
         int index = co->varnames_inv.try_get(name);
         if(index == -1) return nullptr;
         if(index == -1) return nullptr;
         return &a[index];
         return &a[index];
@@ -10,13 +10,13 @@ namespace pkpy{
     NameDict_ FastLocals::to_namedict(){
     NameDict_ FastLocals::to_namedict(){
         NameDict_ dict = std::make_shared<NameDict>();
         NameDict_ dict = std::make_shared<NameDict>();
         co->varnames_inv.apply([&](StrName name, int index){
         co->varnames_inv.apply([&](StrName name, int index){
-            PyObject* value = a[index];
+            PyVar value = a[index];
             if(value != PY_NULL) dict->set(name, value);
             if(value != PY_NULL) dict->set(name, value);
         });
         });
         return dict;
         return dict;
     }
     }
 
 
-    PyObject* Frame::f_closure_try_get(StrName name){
+    PyVar Frame::f_closure_try_get(StrName name){
         if(_callable == nullptr) return nullptr;
         if(_callable == nullptr) return nullptr;
         Function& fn = PK_OBJ_GET(Function, _callable);
         Function& fn = PK_OBJ_GET(Function, _callable);
         if(fn._closure == nullptr) return nullptr;
         if(fn._closure == nullptr) return nullptr;
@@ -31,7 +31,7 @@ namespace pkpy{
             block = co->blocks[block].parent;
             block = co->blocks[block].parent;
         }
         }
         if(block < 0) return false;
         if(block < 0) return false;
-        PyObject* obj = _s->popx();         // pop exception object
+        PyVar obj = _s->popx();         // pop exception object
         // get the stack size of the try block
         // get the stack size of the try block
         int _stack_size = co->blocks[block].base_stack_size;
         int _stack_size = co->blocks[block].base_stack_size;
         if(stack_size(_s) < _stack_size) throw std::runtime_error(_S("invalid state: ", stack_size(_s), '<', _stack_size).str());
         if(stack_size(_s) < _stack_size) throw std::runtime_error(_S("invalid state: ", stack_size(_s), '<', _stack_size).str());

+ 5 - 5
src/gc.cpp

@@ -3,8 +3,8 @@
 namespace pkpy{
 namespace pkpy{
 
 
     int ManagedHeap::sweep(){
     int ManagedHeap::sweep(){
-        std::vector<PyObject*> alive;
-        for(PyObject* obj: gen){
+        std::vector<PyVar> alive;
+        for(PyVar obj: gen){
             if(obj->gc_marked){
             if(obj->gc_marked){
                 obj->gc_marked = false;
                 obj->gc_marked = false;
                 alive.push_back(obj);
                 alive.push_back(obj);
@@ -19,7 +19,7 @@ namespace pkpy{
         }
         }
 
 
         // clear _no_gc marked flag
         // clear _no_gc marked flag
-        for(PyObject* obj: _no_gc) obj->gc_marked = false;
+        for(PyVar obj: _no_gc) obj->gc_marked = false;
 
 
         int freed = gen.size() - alive.size();
         int freed = gen.size() - alive.size();
 
 
@@ -55,8 +55,8 @@ namespace pkpy{
     }
     }
 
 
     ManagedHeap::~ManagedHeap(){
     ManagedHeap::~ManagedHeap(){
-        for(PyObject* obj: _no_gc) { obj->~PyObject(); pool64_dealloc(obj); }
-        for(PyObject* obj: gen) { obj->~PyObject(); pool64_dealloc(obj); }
+        for(PyVar obj: _no_gc) { obj->~PyObject(); pool64_dealloc(obj); }
+        for(PyVar obj: gen) { obj->~PyObject(); pool64_dealloc(obj); }
     }
     }
 
 
 
 

+ 5 - 5
src/io.cpp

@@ -15,7 +15,7 @@ struct FileIO {
 
 
     FileIO(VM* vm, const Str& file, const Str& mode);
     FileIO(VM* vm, const Str& file, const Str& mode);
     void close();
     void close();
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 };
 
 
 static FILE* io_fopen(const char* name, const char* mode){
 static FILE* io_fopen(const char* name, const char* mode){
@@ -53,7 +53,7 @@ unsigned char* _default_import_handler(const char* name, int* out_size){
     return buffer;
     return buffer;
 };
 };
 
 
-void FileIO::_register(VM* vm, PyObject* mod, PyObject* type){
+void FileIO::_register(VM* vm, PyVar mod, PyVar type){
     vm->bind_func(type, __new__, 3, [](VM* vm, ArgsView args){
     vm->bind_func(type, __new__, 3, [](VM* vm, ArgsView args){
         Type cls = PK_OBJ_GET(Type, args[0]);
         Type cls = PK_OBJ_GET(Type, args[0]);
         return vm->heap.gcnew<FileIO>(cls, vm,
         return vm->heap.gcnew<FileIO>(cls, vm,
@@ -138,7 +138,7 @@ void FileIO::close(){
 }
 }
 
 
 void add_module_io(VM* vm){
 void add_module_io(VM* vm){
-    PyObject* mod = vm->new_module("io");
+    PyVar mod = vm->new_module("io");
     vm->register_user_class<FileIO>(mod, "FileIO");
     vm->register_user_class<FileIO>(mod, "FileIO");
 
 
     mod->attr().set("SEEK_SET", VAR(SEEK_SET));
     mod->attr().set("SEEK_SET", VAR(SEEK_SET));
@@ -153,8 +153,8 @@ void add_module_io(VM* vm){
 }
 }
 
 
 void add_module_os(VM* vm){
 void add_module_os(VM* vm){
-    PyObject* mod = vm->new_module("os");
-    PyObject* path_obj = vm->heap.gcnew<DummyInstance>(vm->tp_object);
+    PyVar mod = vm->new_module("os");
+    PyVar path_obj = vm->heap.gcnew<DummyInstance>(vm->tp_object);
     mod->attr().set("path", path_obj);
     mod->attr().set("path", path_obj);
     
     
     // Working directory is shared by all VMs!!
     // Working directory is shared by all VMs!!

+ 20 - 20
src/iter.cpp

@@ -2,9 +2,9 @@
 
 
 namespace pkpy{
 namespace pkpy{
 
 
-    void RangeIter::_register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0){ return _0; });
-        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) -> unsigned{
+    void RangeIter::_register(VM* vm, PyVar mod, PyVar type){
+        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0){ return _0; });
+        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) -> unsigned{
             RangeIter& self = PK_OBJ_GET(RangeIter, _0);
             RangeIter& self = PK_OBJ_GET(RangeIter, _0);
             if(self.r.step > 0){
             if(self.r.step > 0){
                 if(self.current >= self.r.stop) return 0;
                 if(self.current >= self.r.stop) return 0;
@@ -17,9 +17,9 @@ namespace pkpy{
         });
         });
     }
     }
 
 
-    void ArrayIter::_register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0){ return _0; });
-        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) -> unsigned{
+    void ArrayIter::_register(VM* vm, PyVar mod, PyVar type){
+        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0){ return _0; });
+        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) -> unsigned{
             ArrayIter& self = _CAST(ArrayIter&, _0);
             ArrayIter& self = _CAST(ArrayIter&, _0);
             if(self.current == self.end) return 0;
             if(self.current == self.end) return 0;
             vm->s_data.push(*self.current++);
             vm->s_data.push(*self.current++);
@@ -27,9 +27,9 @@ namespace pkpy{
         });
         });
     }
     }
 
 
-    void StringIter::_register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0){ return _0; });
-        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) -> unsigned{
+    void StringIter::_register(VM* vm, PyVar mod, PyVar type){
+        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0){ return _0; });
+        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) -> unsigned{
             StringIter& self = _CAST(StringIter&, _0);
             StringIter& self = _CAST(StringIter&, _0);
             Str& s = PK_OBJ_GET(Str, self.ref);
             Str& s = PK_OBJ_GET(Str, self.ref);
             if(self.i == s.size) return 0;
             if(self.i == s.size) return 0;
@@ -41,17 +41,17 @@ namespace pkpy{
         });
         });
     }
     }
 
 
-    PyObject* Generator::next(VM* vm){
+    PyVar Generator::next(VM* vm){
         if(state == 2) return vm->StopIteration;
         if(state == 2) return vm->StopIteration;
         // reset frame._sp_base
         // reset frame._sp_base
         frame._sp_base = vm->s_data._sp;
         frame._sp_base = vm->s_data._sp;
         frame._locals.a = vm->s_data._sp;
         frame._locals.a = vm->s_data._sp;
         // restore the context
         // restore the context
-        for(PyObject* obj: s_backup) vm->s_data.push(obj);
+        for(PyVar obj: s_backup) vm->s_data.push(obj);
         s_backup.clear();
         s_backup.clear();
         vm->callstack.emplace(std::move(frame));
         vm->callstack.emplace(std::move(frame));
 
 
-        PyObject* ret;
+        PyVar ret;
         try{
         try{
             ret = vm->__run_top_frame();
             ret = vm->__run_top_frame();
         }catch(...){
         }catch(...){
@@ -63,7 +63,7 @@ namespace pkpy{
             // backup the context
             // backup the context
             frame = std::move(vm->callstack.top());
             frame = std::move(vm->callstack.top());
             ret = vm->s_data.popx();
             ret = vm->s_data.popx();
-            for(PyObject* obj: frame.stack_view(&vm->s_data)) s_backup.push_back(obj);
+            for(PyVar obj: frame.stack_view(&vm->s_data)) s_backup.push_back(obj);
             vm->__pop_frame();
             vm->__pop_frame();
             state = 1;
             state = 1;
             if(ret == vm->StopIteration) state = 2;
             if(ret == vm->StopIteration) state = 2;
@@ -74,11 +74,11 @@ namespace pkpy{
         }
         }
     }
     }
 
 
-    void Generator::_register(VM* vm, PyObject* mod, PyObject* type){
-        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0){ return _0; });
-        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) -> unsigned{
+    void Generator::_register(VM* vm, PyVar mod, PyVar type){
+        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0){ return _0; });
+        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) -> unsigned{
             Generator& self = _CAST(Generator&, _0);
             Generator& self = _CAST(Generator&, _0);
-            PyObject* retval = self.next(vm);
+            PyVar retval = self.next(vm);
             if(retval == vm->StopIteration) return 0;
             if(retval == vm->StopIteration) return 0;
             vm->s_data.push(retval);
             vm->s_data.push(retval);
             return 1;
             return 1;
@@ -86,8 +86,8 @@ namespace pkpy{
     }
     }
 
 
     void DictItemsIter::_register(VM *vm, PyObject *mod, PyObject *type){
     void DictItemsIter::_register(VM *vm, PyObject *mod, PyObject *type){
-        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0){ return _0; });
-        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0) -> unsigned{
+        vm->bind__iter__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0){ return _0; });
+        vm->bind__next__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0) -> unsigned{
             DictItemsIter& self = _CAST(DictItemsIter&, _0);
             DictItemsIter& self = _CAST(DictItemsIter&, _0);
             Dict& d = PK_OBJ_GET(Dict, self.ref);
             Dict& d = PK_OBJ_GET(Dict, self.ref);
             if(self.i == -1) return 0;
             if(self.i == -1) return 0;
@@ -98,7 +98,7 @@ namespace pkpy{
         });
         });
     }
     }
 
 
-PyObject* VM::__py_generator(Frame&& frame, ArgsView buffer){
+PyVar VM::__py_generator(Frame&& frame, ArgsView buffer){
     return vm->new_user_object<Generator>(std::move(frame), buffer);
     return vm->new_user_object<Generator>(std::move(frame), buffer);
 }
 }
 
 

+ 23 - 23
src/linalg.cpp

@@ -3,14 +3,14 @@
 namespace pkpy{
 namespace pkpy{
 
 
 #define BIND_VEC_VEC_OP(D, name, op)                                                    \
 #define BIND_VEC_VEC_OP(D, name, op)                                                    \
-        vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){  \
+        vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){  \
             Vec##D& self = _CAST(Vec##D&, _0);                                      \
             Vec##D& self = _CAST(Vec##D&, _0);                                      \
             Vec##D& other = CAST(Vec##D&, _1);                                      \
             Vec##D& other = CAST(Vec##D&, _1);                                      \
             return VAR(self op other);                                                  \
             return VAR(self op other);                                                  \
         });
         });
 
 
 #define BIND_VEC_FLOAT_OP(D, name, op)  \
 #define BIND_VEC_FLOAT_OP(D, name, op)  \
-        vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){  \
+        vm->bind##name(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){  \
             Vec##D& self = _CAST(Vec##D&, _0);                                      \
             Vec##D& self = _CAST(Vec##D&, _0);                                      \
             f64 other = CAST(f64, _1);                                                  \
             f64 other = CAST(f64, _1);                                                  \
             return VAR(self op other);                                                  \
             return VAR(self op other);                                                  \
@@ -30,7 +30,7 @@ namespace pkpy{
         });
         });
 
 
 #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, PyVar _0, PyVar _1){     \
             Vec##D& self = _CAST(Vec##D&, _0);                                          \
             Vec##D& self = _CAST(Vec##D&, _0);                                          \
             if(vm->is_user_type<Vec##D>(_1)){                                               \
             if(vm->is_user_type<Vec##D>(_1)){                                               \
                 Vec##D& other = _CAST(Vec##D&, _1);                                     \
                 Vec##D& other = _CAST(Vec##D&, _1);                                     \
@@ -44,14 +44,14 @@ namespace pkpy{
             f64 other = CAST(f64, args[1]);                                                 \
             f64 other = CAST(f64, args[1]);                                                 \
             return VAR(self * other);                                                       \
             return VAR(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, PyVar _0, PyVar _1){ \
             Vec##D& self = _CAST(Vec##D&, _0);                                          \
             Vec##D& self = _CAST(Vec##D&, _0);                                          \
             f64 other = CAST(f64, _1);                                                      \
             f64 other = CAST(f64, _1);                                                      \
             return VAR(self / other);                                                       \
             return VAR(self / other);                                                       \
         });
         });
 
 
 #define BIND_VEC_GETITEM(D) \
 #define BIND_VEC_GETITEM(D) \
-        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj, PyObject* index){ \
+        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj, PyVar index){ \
             Vec##D& self = _CAST(Vec##D&, obj); \
             Vec##D& self = _CAST(Vec##D&, obj); \
             i64 i = CAST(i64, index); \
             i64 i = CAST(i64, index); \
             if(i < 0 || i >= D) vm->IndexError("index out of range"); \
             if(i < 0 || i >= D) vm->IndexError("index out of range"); \
@@ -114,7 +114,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
     return Vec2(output_x, output_y);
     return Vec2(output_x, output_y);
 }
 }
 
 
-    void Vec2::_register(VM* vm, PyObject* mod, PyObject* type){
+    void Vec2::_register(VM* vm, PyVar mod, PyVar type){
         PY_STRUCT_LIKE(Vec2)
         PY_STRUCT_LIKE(Vec2)
 
 
         type->attr().set("ZERO", vm->new_user_object<Vec2>(0, 0));
         type->attr().set("ZERO", vm->new_user_object<Vec2>(0, 0));
@@ -149,7 +149,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return VAR(val);
             return VAR(val);
         }, {}, BindType::STATICMETHOD);
         }, {}, BindType::STATICMETHOD);
 
 
-        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj) -> Str{
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj) -> Str{
             Vec2 self = _CAST(Vec2&, obj);
             Vec2 self = _CAST(Vec2&, obj);
             SStream ss;
             SStream ss;
             ss.setprecision(3);
             ss.setprecision(3);
@@ -187,7 +187,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
         BIND_VEC_GETITEM(2)
         BIND_VEC_GETITEM(2)
     }
     }
 
 
-    void Vec3::_register(VM* vm, PyObject* mod, PyObject* type){
+    void Vec3::_register(VM* vm, PyVar mod, PyVar type){
         PY_STRUCT_LIKE(Vec3)
         PY_STRUCT_LIKE(Vec3)
 
 
         type->attr().set("ZERO", vm->new_user_object<Vec3>(0, 0, 0));
         type->attr().set("ZERO", vm->new_user_object<Vec3>(0, 0, 0));
@@ -200,7 +200,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return vm->heap.gcnew<Vec3>(PK_OBJ_GET(Type, args[0]), x, y, z);
             return vm->heap.gcnew<Vec3>(PK_OBJ_GET(Type, args[0]), x, y, z);
         });
         });
 
 
-        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj) -> Str{
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj) -> Str{
             Vec3 self = _CAST(Vec3&, obj);
             Vec3 self = _CAST(Vec3&, obj);
             SStream ss;
             SStream ss;
             ss.setprecision(3);
             ss.setprecision(3);
@@ -225,7 +225,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
         BIND_VEC_GETITEM(3)
         BIND_VEC_GETITEM(3)
     }
     }
 
 
-    void Vec4::_register(VM* vm, PyObject* mod, PyObject* type){
+    void Vec4::_register(VM* vm, PyVar mod, PyVar type){
         PY_STRUCT_LIKE(Vec4)
         PY_STRUCT_LIKE(Vec4)
 
 
         type->attr().set("ZERO", vm->new_user_object<Vec4>(0, 0, 0, 0));
         type->attr().set("ZERO", vm->new_user_object<Vec4>(0, 0, 0, 0));
@@ -239,7 +239,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return vm->heap.gcnew<Vec4>(PK_OBJ_GET(Type, args[0]), x, y, z, w);
             return vm->heap.gcnew<Vec4>(PK_OBJ_GET(Type, args[0]), x, y, z, w);
         });
         });
 
 
-        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj) -> Str{
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj) -> Str{
             Vec4 self = _CAST(Vec4&, obj);
             Vec4 self = _CAST(Vec4&, obj);
             SStream ss;
             SStream ss;
             ss.setprecision(3);
             ss.setprecision(3);
@@ -270,7 +270,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
 #undef BIND_VEC_FUNCTION_1
 #undef BIND_VEC_FUNCTION_1
 #undef BIND_VEC_GETITEM
 #undef BIND_VEC_GETITEM
 
 
-    void Mat3x3::_register(VM* vm, PyObject* mod, PyObject* type){
+    void Mat3x3::_register(VM* vm, PyVar mod, PyVar type){
         PY_STRUCT_LIKE(Mat3x3)
         PY_STRUCT_LIKE(Mat3x3)
 
 
         vm->bind_func(type, __new__, -1, [](VM* vm, ArgsView args){
         vm->bind_func(type, __new__, -1, [](VM* vm, ArgsView args){
@@ -298,7 +298,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return vm->None;
             return vm->None;
         });
         });
 
 
-        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj) -> Str{
+        vm->bind__repr__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj) -> Str{
             const Mat3x3& self = _CAST(Mat3x3&, obj);
             const Mat3x3& self = _CAST(Mat3x3&, obj);
             SStream ss;
             SStream ss;
             ss.setprecision(3);
             ss.setprecision(3);
@@ -308,7 +308,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return ss.str();
             return ss.str();
         });
         });
 
 
-        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj, PyObject* index){
+        vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj, PyVar index){
             Mat3x3& self = _CAST(Mat3x3&, obj);
             Mat3x3& self = _CAST(Mat3x3&, obj);
             Tuple& t = CAST(Tuple&, index);
             Tuple& t = CAST(Tuple&, index);
             if(t.size() != 2){
             if(t.size() != 2){
@@ -322,7 +322,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return VAR(self.m[i][j]);
             return VAR(self.m[i][j]);
         });
         });
 
 
-        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* obj, PyObject* index, PyObject* value){
+        vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar obj, PyVar index, PyVar value){
             Mat3x3& self = _CAST(Mat3x3&, obj);
             Mat3x3& self = _CAST(Mat3x3&, obj);
             const Tuple& t = CAST(Tuple&, index);
             const Tuple& t = CAST(Tuple&, index);
             if(t.size() != 2){
             if(t.size() != 2){
@@ -346,19 +346,19 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
         vm->bind_field(type, "_32", &Mat3x3::_32);
         vm->bind_field(type, "_32", &Mat3x3::_32);
         vm->bind_field(type, "_33", &Mat3x3::_33);
         vm->bind_field(type, "_33", &Mat3x3::_33);
 
 
-        vm->bind__add__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){
+        vm->bind__add__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){
             Mat3x3& self = _CAST(Mat3x3&, _0);
             Mat3x3& self = _CAST(Mat3x3&, _0);
             Mat3x3& other = CAST(Mat3x3&, _1);
             Mat3x3& other = CAST(Mat3x3&, _1);
             return vm->new_user_object<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, PyVar _0, PyVar _1){
             Mat3x3& self = _CAST(Mat3x3&, _0);
             Mat3x3& self = _CAST(Mat3x3&, _0);
             Mat3x3& other = CAST(Mat3x3&, _1);
             Mat3x3& other = CAST(Mat3x3&, _1);
             return vm->new_user_object<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, PyVar _0, PyVar _1){
             Mat3x3& self = _CAST(Mat3x3&, _0);
             Mat3x3& self = _CAST(Mat3x3&, _0);
             f64 other = CAST_F(_1);
             f64 other = CAST_F(_1);
             return vm->new_user_object<Mat3x3>(self * other);
             return vm->new_user_object<Mat3x3>(self * other);
@@ -370,13 +370,13 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return vm->new_user_object<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, PyVar _0, PyVar _1){
             Mat3x3& self = _CAST(Mat3x3&, _0);
             Mat3x3& self = _CAST(Mat3x3&, _0);
             f64 other = CAST_F(_1);
             f64 other = CAST_F(_1);
             return vm->new_user_object<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, PyVar _0, PyVar _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);
@@ -411,7 +411,7 @@ static Vec2 SmoothDamp(Vec2 current, Vec2 target, Vec2& currentVelocity, float s
             return vm->new_user_object<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, PyVar 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");
@@ -548,14 +548,14 @@ 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");
+    PyVar linalg = vm->new_module("linalg");
 
 
     vm->register_user_class<Vec2>(linalg, "vec2", VM::tp_object, true);
     vm->register_user_class<Vec2>(linalg, "vec2", VM::tp_object, true);
     vm->register_user_class<Vec3>(linalg, "vec3", VM::tp_object, true);
     vm->register_user_class<Vec3>(linalg, "vec3", VM::tp_object, true);
     vm->register_user_class<Vec4>(linalg, "vec4", VM::tp_object, true);
     vm->register_user_class<Vec4>(linalg, "vec4", VM::tp_object, true);
     vm->register_user_class<Mat3x3>(linalg, "mat3x3", VM::tp_object, true);
     vm->register_user_class<Mat3x3>(linalg, "mat3x3", VM::tp_object, true);
 
 
-    PyObject* float_p = vm->_modules["c"]->attr("float_p");
+    PyVar float_p = vm->_modules["c"]->attr("float_p");
     linalg->attr().set("vec2_p", float_p);
     linalg->attr().set("vec2_p", float_p);
     linalg->attr().set("vec3_p", float_p);
     linalg->attr().set("vec3_p", float_p);
     linalg->attr().set("vec4_p", float_p);
     linalg->attr().set("vec4_p", float_p);

+ 22 - 22
src/modules.cpp

@@ -26,7 +26,7 @@ struct PyStructTime{
         tm_isdst = tm->tm_isdst;
         tm_isdst = tm->tm_isdst;
     }
     }
 
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type){
+    static void _register(VM* vm, PyVar mod, PyVar type){
         PY_READONLY_FIELD(PyStructTime, "tm_year", tm_year);
         PY_READONLY_FIELD(PyStructTime, "tm_year", tm_year);
         PY_READONLY_FIELD(PyStructTime, "tm_mon", tm_mon);
         PY_READONLY_FIELD(PyStructTime, "tm_mon", tm_mon);
         PY_READONLY_FIELD(PyStructTime, "tm_mday", tm_mday);
         PY_READONLY_FIELD(PyStructTime, "tm_mday", tm_mday);
@@ -40,7 +40,7 @@ struct PyStructTime{
 };
 };
 
 
 void add_module_time(VM* vm){
 void add_module_time(VM* vm){
-    PyObject* mod = vm->new_module("time");
+    PyVar mod = vm->new_module("time");
     vm->register_user_class<PyStructTime>(mod, "struct_time");
     vm->register_user_class<PyStructTime>(mod, "struct_time");
 
 
     vm->bind_func(mod, "time", 0, [](VM* vm, ArgsView args) {
     vm->bind_func(mod, "time", 0, [](VM* vm, ArgsView args) {
@@ -67,12 +67,12 @@ void add_module_time(VM* vm){
 }
 }
 
 
 void add_module_sys(VM* vm){
 void add_module_sys(VM* vm){
-    PyObject* mod = vm->new_module("sys");
+    PyVar mod = vm->new_module("sys");
     vm->setattr(mod, "version", VAR(PK_VERSION));
     vm->setattr(mod, "version", VAR(PK_VERSION));
     vm->setattr(mod, "platform", VAR(kPlatformStrings[PK_SYS_PLATFORM]));
     vm->setattr(mod, "platform", VAR(kPlatformStrings[PK_SYS_PLATFORM]));
 
 
-    PyObject* stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
-    PyObject* stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
+    PyVar stdout_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
+    PyVar stderr_ = vm->heap.gcnew<DummyInstance>(vm->tp_object);
     vm->setattr(mod, "stdout", stdout_);
     vm->setattr(mod, "stdout", stdout_);
     vm->setattr(mod, "stderr", stderr_);
     vm->setattr(mod, "stderr", stderr_);
 
 
@@ -90,7 +90,7 @@ void add_module_sys(VM* vm){
 }
 }
 
 
 void add_module_json(VM* vm){
 void add_module_json(VM* vm){
-    PyObject* mod = vm->new_module("json");
+    PyVar mod = vm->new_module("json");
     vm->bind_func(mod, "loads", 1, [](VM* vm, ArgsView args) {
     vm->bind_func(mod, "loads", 1, [](VM* vm, ArgsView args) {
         std::string_view sv;
         std::string_view sv;
         if(is_type(args[0], vm->tp_bytes)){
         if(is_type(args[0], vm->tp_bytes)){
@@ -109,7 +109,7 @@ void add_module_json(VM* vm){
 
 
 // https://docs.python.org/3.5/library/math.html
 // https://docs.python.org/3.5/library/math.html
 void add_module_math(VM* vm){
 void add_module_math(VM* vm){
-    PyObject* mod = vm->new_module("math");
+    PyVar mod = vm->new_module("math");
     mod->attr().set("pi", VAR(3.1415926535897932384));
     mod->attr().set("pi", VAR(3.1415926535897932384));
     mod->attr().set("e" , VAR(2.7182818284590452354));
     mod->attr().set("e" , VAR(2.7182818284590452354));
     mod->attr().set("inf", VAR(std::numeric_limits<double>::infinity()));
     mod->attr().set("inf", VAR(std::numeric_limits<double>::infinity()));
@@ -122,7 +122,7 @@ void add_module_math(VM* vm){
         List& list = CAST(List&, args[0]);
         List& list = CAST(List&, args[0]);
         double sum = 0;
         double sum = 0;
         double c = 0;
         double c = 0;
-        for(PyObject* arg : list){
+        for(PyVar arg : list){
             double x = CAST_F(arg);
             double x = CAST_F(arg);
             double y = x - c;
             double y = x - c;
             double t = sum + y;
             double t = sum + y;
@@ -196,7 +196,7 @@ void add_module_math(VM* vm){
 }
 }
 
 
 void add_module_traceback(VM* vm){
 void add_module_traceback(VM* vm){
-    PyObject* mod = vm->new_module("traceback");
+    PyVar mod = vm->new_module("traceback");
     vm->bind_func(mod, "print_exc", 0, [](VM* vm, ArgsView args) {
     vm->bind_func(mod, "print_exc", 0, [](VM* vm, ArgsView args) {
         if(vm->__last_exception==nullptr) vm->ValueError("no exception");
         if(vm->__last_exception==nullptr) vm->ValueError("no exception");
         Exception& e = _CAST(Exception&, vm->__last_exception);
         Exception& e = _CAST(Exception&, vm->__last_exception);
@@ -212,16 +212,16 @@ void add_module_traceback(VM* vm){
 }
 }
 
 
 void add_module_dis(VM* vm){
 void add_module_dis(VM* vm){
-    PyObject* mod = vm->new_module("dis");
+    PyVar mod = vm->new_module("dis");
 
 
     vm->bind_func(mod, "dis", 1, [](VM* vm, ArgsView args) {
     vm->bind_func(mod, "dis", 1, [](VM* vm, ArgsView args) {
         CodeObject_ code;
         CodeObject_ code;
-        PyObject* obj = args[0];
+        PyVar obj = args[0];
         if(is_type(obj, vm->tp_str)){
         if(is_type(obj, vm->tp_str)){
             const Str& source = CAST(Str, obj);
             const Str& source = CAST(Str, obj);
             code = vm->compile(source, "<dis>", EXEC_MODE);
             code = vm->compile(source, "<dis>", EXEC_MODE);
         }
         }
-        PyObject* f = obj;
+        PyVar f = obj;
         if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, obj).func;
         if(is_type(f, vm->tp_bound_method)) f = CAST(BoundMethod, obj).func;
         code = CAST(Function&, f).decl->code;
         code = CAST(Function&, f).decl->code;
         vm->stdout_write(vm->disassemble(code));
         vm->stdout_write(vm->disassemble(code));
@@ -230,15 +230,15 @@ void add_module_dis(VM* vm){
 }
 }
 
 
 void add_module_gc(VM* vm){
 void add_module_gc(VM* vm){
-    PyObject* mod = vm->new_module("gc");
+    PyVar mod = vm->new_module("gc");
     vm->bind_func(mod, "collect", 0, PK_LAMBDA(VAR(vm->heap.collect())));
     vm->bind_func(mod, "collect", 0, PK_LAMBDA(VAR(vm->heap.collect())));
 }
 }
 
 
 void add_module_enum(VM* vm){
 void add_module_enum(VM* vm){
-    PyObject* mod = vm->new_module("enum");
+    PyVar mod = vm->new_module("enum");
     CodeObject_ code = vm->compile(kPythonLibs__enum, "enum.py", EXEC_MODE);
     CodeObject_ code = vm->compile(kPythonLibs__enum, "enum.py", EXEC_MODE);
     vm->_exec(code, mod);
     vm->_exec(code, mod);
-    PyObject* Enum = mod->attr("Enum");
+    PyVar Enum = mod->attr("Enum");
     vm->_all_types[PK_OBJ_GET(Type, Enum).index].on_end_subclass = \
     vm->_all_types[PK_OBJ_GET(Type, Enum).index].on_end_subclass = \
         [](VM* vm, PyTypeInfo* new_ti){
         [](VM* vm, PyTypeInfo* new_ti){
             new_ti->subclass_enabled = false;    // Enum class cannot be subclassed twice
             new_ti->subclass_enabled = false;    // Enum class cannot be subclassed twice
@@ -253,14 +253,14 @@ void add_module_enum(VM* vm){
 }
 }
 
 
 void add_module___builtins(VM* vm){
 void add_module___builtins(VM* vm){
-    PyObject* mod = vm->new_module("__builtins");
+    PyVar mod = vm->new_module("__builtins");
 
 
     vm->bind_func(mod, "next", 1, [](VM* vm, ArgsView args){
     vm->bind_func(mod, "next", 1, [](VM* vm, ArgsView args){
         return vm->py_next(args[0]);
         return vm->py_next(args[0]);
     });
     });
 
 
     vm->bind_func(mod, "_enable_instance_dict", 1, [](VM* vm, ArgsView args){
     vm->bind_func(mod, "_enable_instance_dict", 1, [](VM* vm, ArgsView args){
-        PyObject* self = args[0];
+        PyVar self = args[0];
         if(is_tagged(self)) vm->TypeError("object: tagged object cannot enable instance dict");
         if(is_tagged(self)) vm->TypeError("object: tagged object cannot enable instance dict");
         if(self->is_attr_valid()) vm->RuntimeError("object: instance dict is already enabled");
         if(self->is_attr_valid()) vm->RuntimeError("object: instance dict is already enabled");
         self->_enable_instance_dict();
         self->_enable_instance_dict();
@@ -284,7 +284,7 @@ struct _LpGuard{
 struct LineProfilerW{
 struct LineProfilerW{
     LineProfiler profiler;
     LineProfiler profiler;
 
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type){
+    static void _register(VM* vm, PyVar mod, PyVar type){
         vm->bind_func(type, __new__, 1, [](VM* vm, ArgsView args){
         vm->bind_func(type, __new__, 1, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             Type cls = PK_OBJ_GET(Type, args[0]);
             return vm->heap.gcnew<LineProfilerW>(cls);
             return vm->heap.gcnew<LineProfilerW>(cls);
@@ -300,13 +300,13 @@ struct LineProfilerW{
 
 
         vm->bind(type, "runcall(self, func, *args)", [](VM* vm, ArgsView view){
         vm->bind(type, "runcall(self, func, *args)", [](VM* vm, ArgsView view){
             LineProfilerW& self = PK_OBJ_GET(LineProfilerW, view[0]);
             LineProfilerW& self = PK_OBJ_GET(LineProfilerW, view[0]);
-            PyObject* func = view[1];
+            PyVar func = view[1];
             const Tuple& args = CAST(Tuple&, view[2]);
             const Tuple& args = CAST(Tuple&, view[2]);
             vm->s_data.push(func);
             vm->s_data.push(func);
             vm->s_data.push(PY_NULL);
             vm->s_data.push(PY_NULL);
-            for(PyObject* arg : args) vm->s_data.push(arg);
+            for(PyVar arg : args) vm->s_data.push(arg);
             _LpGuard guard(&self, vm);
             _LpGuard guard(&self, vm);
-            PyObject* ret = vm->vectorcall(args.size());
+            PyVar ret = vm->vectorcall(args.size());
             return ret;
             return ret;
         });
         });
 
 
@@ -333,7 +333,7 @@ _LpGuard::~_LpGuard(){
 }
 }
 
 
 void add_module_line_profiler(VM *vm){
 void add_module_line_profiler(VM *vm){
-    PyObject* mod = vm->new_module("line_profiler");
+    PyVar mod = vm->new_module("line_profiler");
     vm->register_user_class<LineProfilerW>(mod, "LineProfiler");
     vm->register_user_class<LineProfilerW>(mod, "LineProfiler");
 }
 }
 #else
 #else

+ 120 - 120
src/pocketpy.cpp

@@ -7,7 +7,7 @@ void add_module_cjson(VM* vm);
 #endif
 #endif
 
 
 template<typename T>
 template<typename T>
-PyObject* PyArrayGetItem(VM* vm, PyObject* _0, PyObject* _1){
+PyVar PyArrayGetItem(VM* vm, PyVar _0, PyVar _1){
     static_assert(std::is_same_v<T, List> || std::is_same_v<T, Tuple>);
     static_assert(std::is_same_v<T, List> || std::is_same_v<T, Tuple>);
     const T& self = _CAST(T&, _0);
     const T& self = _CAST(T&, _0);
     i64 index;
     i64 index;
@@ -29,13 +29,13 @@ PyObject* PyArrayGetItem(VM* vm, PyObject* _0, PyObject* _1){
 
 
 void __init_builtins(VM* _vm) {
 void __init_builtins(VM* _vm) {
 #define BIND_NUM_ARITH_OPT(name, op)                                                                    \
 #define BIND_NUM_ARITH_OPT(name, op)                                                                    \
-    _vm->bind##name(VM::tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) {                              \
+    _vm->bind##name(VM::tp_int, [](VM* vm, PyVar lhs, PyVar rhs) {                              \
         i64 val;                                                                                        \
         i64 val;                                                                                        \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(i64, lhs) op val);                                 \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(i64, lhs) op val);                                 \
         if(is_float(rhs)) return VAR(_CAST(i64, lhs) op _CAST(f64, rhs));                               \
         if(is_float(rhs)) return VAR(_CAST(i64, lhs) op _CAST(f64, rhs));                               \
         return vm->NotImplemented;                                                                      \
         return vm->NotImplemented;                                                                      \
     });                                                                                                 \
     });                                                                                                 \
-    _vm->bind##name(VM::tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) {                            \
+    _vm->bind##name(VM::tp_float, [](VM* vm, PyVar lhs, PyVar rhs) {                            \
         i64 val;                                                                                        \
         i64 val;                                                                                        \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(f64, lhs) op val);                                 \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(f64, lhs) op val);                                 \
         if(is_float(rhs)) return VAR(_CAST(f64, lhs) op _CAST(f64, rhs));                               \
         if(is_float(rhs)) return VAR(_CAST(f64, lhs) op _CAST(f64, rhs));                               \
@@ -49,13 +49,13 @@ void __init_builtins(VM* _vm) {
 #undef BIND_NUM_ARITH_OPT
 #undef BIND_NUM_ARITH_OPT
 
 
 #define BIND_NUM_LOGICAL_OPT(name, op)   \
 #define BIND_NUM_LOGICAL_OPT(name, op)   \
-    _vm->bind##name(VM::tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) {      \
+    _vm->bind##name(VM::tp_int, [](VM* vm, PyVar lhs, PyVar rhs) {      \
         i64 val;                                                                \
         i64 val;                                                                \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(i64, lhs) op val);         \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(i64, lhs) op val);         \
         if(is_float(rhs))   return VAR(_CAST(i64, lhs) op _CAST(f64, rhs));     \
         if(is_float(rhs))   return VAR(_CAST(i64, lhs) op _CAST(f64, rhs));     \
         return vm->NotImplemented;                                              \
         return vm->NotImplemented;                                              \
     });                                                                         \
     });                                                                         \
-    _vm->bind##name(VM::tp_float, [](VM* vm, PyObject* lhs, PyObject* rhs) {    \
+    _vm->bind##name(VM::tp_float, [](VM* vm, PyVar lhs, PyVar rhs) {    \
         i64 val;                                                                \
         i64 val;                                                                \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(f64, lhs) op val);         \
         if(try_cast_int(rhs, &val)) return VAR(_CAST(f64, lhs) op val);         \
         if(is_float(rhs))   return VAR(_CAST(f64, lhs) op _CAST(f64, rhs));     \
         if(is_float(rhs))   return VAR(_CAST(f64, lhs) op _CAST(f64, rhs));     \
@@ -80,8 +80,8 @@ void __init_builtins(VM* _vm) {
     });
     });
 
 
     _vm->bind_func(_vm->builtins, "super", -1, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "super", -1, [](VM* vm, ArgsView args) {
-        PyObject* class_arg = nullptr;
-        PyObject* self_arg = nullptr;
+        PyVar class_arg = nullptr;
+        PyVar self_arg = nullptr;
         if(args.size() == 2){
         if(args.size() == 2){
             class_arg = args[0];
             class_arg = args[0];
             self_arg = args[1];
             self_arg = args[1];
@@ -108,13 +108,13 @@ void __init_builtins(VM* _vm) {
     });
     });
 
 
     _vm->bind_func(_vm->builtins, "staticmethod", 1, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "staticmethod", 1, [](VM* vm, ArgsView args) {
-        PyObject* func = args[0];
+        PyVar func = args[0];
         vm->check_type(func, vm->tp_function);
         vm->check_type(func, vm->tp_function);
         return vm->heap.gcnew<StaticMethod>(vm->tp_staticmethod, args[0]);
         return vm->heap.gcnew<StaticMethod>(vm->tp_staticmethod, args[0]);
     });
     });
 
 
     _vm->bind_func(_vm->builtins, "classmethod", 1, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "classmethod", 1, [](VM* vm, ArgsView args) {
-        PyObject* func = args[0];
+        PyVar func = args[0];
         vm->check_type(func, vm->tp_function);
         vm->check_type(func, vm->tp_function);
         return vm->heap.gcnew<ClassMethod>(vm->tp_classmethod, args[0]);
         return vm->heap.gcnew<ClassMethod>(vm->tp_classmethod, args[0]);
     });
     });
@@ -122,7 +122,7 @@ void __init_builtins(VM* _vm) {
     _vm->bind_func(_vm->builtins, "isinstance", 2, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "isinstance", 2, [](VM* vm, ArgsView args) {
         if(is_type(args[1], vm->tp_tuple)){
         if(is_type(args[1], vm->tp_tuple)){
             Tuple& types = _CAST(Tuple&, args[1]);
             Tuple& types = _CAST(Tuple&, args[1]);
-            for(PyObject* type : types){
+            for(PyVar type : types){
                 vm->check_type(type, vm->tp_type);
                 vm->check_type(type, vm->tp_type);
                 if(vm->isinstance(args[0], PK_OBJ_GET(Type, type))) return vm->True;
                 if(vm->isinstance(args[0], PK_OBJ_GET(Type, type))) return vm->True;
             }
             }
@@ -140,7 +140,7 @@ void __init_builtins(VM* _vm) {
     });
     });
 
 
     _vm->bind_func(_vm->builtins, "globals", 0, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "globals", 0, [](VM* vm, ArgsView args) {
-        PyObject* mod = vm->callstack.top()._module;
+        PyVar mod = vm->callstack.top()._module;
         return VAR(MappingProxy(mod));
         return VAR(MappingProxy(mod));
     });
     });
 
 
@@ -171,7 +171,7 @@ void __init_builtins(VM* _vm) {
     });
     });
 
 
     _vm->bind_func(_vm->builtins, "id", 1, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "id", 1, [](VM* vm, ArgsView args) {
-        PyObject* obj = args[0];
+        PyVar obj = args[0];
         if(is_tagged(obj)) return vm->None;
         if(is_tagged(obj)) return vm->None;
         return VAR(PK_BITS(obj));
         return VAR(PK_BITS(obj));
     });
     });
@@ -267,7 +267,7 @@ void __init_builtins(VM* _vm) {
     _vm->bind_func(_vm->builtins, "getattr", -1, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "getattr", -1, [](VM* vm, ArgsView args) {
         if(args.size()!=2 && args.size()!=3) vm->TypeError("getattr() takes 2 or 3 arguments");
         if(args.size()!=2 && args.size()!=3) vm->TypeError("getattr() takes 2 or 3 arguments");
         StrName name = CAST(Str&, args[1]);
         StrName name = CAST(Str&, args[1]);
-        PyObject* val = vm->getattr(args[0], name, false);
+        PyVar val = vm->getattr(args[0], name, false);
         if(val == nullptr){
         if(val == nullptr){
             if(args.size()==2) vm->AttributeError(args[0], name);
             if(args.size()==2) vm->AttributeError(args[0], name);
             return args[2];
             return args[2];
@@ -291,7 +291,7 @@ void __init_builtins(VM* _vm) {
     });
     });
 
 
     _vm->bind_func(_vm->builtins, "next", 1, [](VM* vm, ArgsView args) {
     _vm->bind_func(_vm->builtins, "next", 1, [](VM* vm, ArgsView args) {
-        PyObject* retval = vm->py_next(args[0]);
+        PyVar retval = vm->py_next(args[0]);
         if(retval == vm->StopIteration) vm->_error(vm->call(vm->StopIteration));
         if(retval == vm->StopIteration) vm->_error(vm->call(vm->StopIteration));
         return retval;
         return retval;
     });
     });
@@ -327,7 +327,7 @@ void __init_builtins(VM* _vm) {
     });
     });
 
 
     // tp_object
     // tp_object
-    _vm->bind__repr__(VM::tp_object, [](VM* vm, PyObject* obj) -> Str{
+    _vm->bind__repr__(VM::tp_object, [](VM* vm, PyVar obj) -> Str{
         if(is_tagged(obj)) PK_FATAL_ERROR();
         if(is_tagged(obj)) PK_FATAL_ERROR();
         SStream ss;
         SStream ss;
         ss << "<" << _type_name(vm, vm->_tp(obj)) << " object at ";
         ss << "<" << _type_name(vm, vm->_tp(obj)) << " object at ";
@@ -336,7 +336,7 @@ void __init_builtins(VM* _vm) {
         return ss.str();
         return ss.str();
     });
     });
 
 
-    _vm->bind__eq__(VM::tp_object, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__eq__(VM::tp_object, [](VM* vm, PyVar _0, PyVar _1) {
         return VAR(_0 == _1); 
         return VAR(_0 == _1); 
     });
     });
 
 
@@ -363,24 +363,24 @@ void __init_builtins(VM* _vm) {
         return VAR(r);
         return VAR(r);
     });
     });
 
 
-    _vm->bind__iter__(VM::tp_range, [](VM* vm, PyObject* obj) { return vm->new_user_object<RangeIter>(PK_OBJ_GET(Range, obj)); });
+    _vm->bind__iter__(VM::tp_range, [](VM* vm, PyVar 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) -> Str {
+    _vm->bind__repr__(_vm->_tp(_vm->None), [](VM* vm, PyVar _0) -> Str {
         return "None"; 
         return "None"; 
     });
     });
 
 
     // tp_float / tp_float
     // tp_float / tp_float
-    _vm->bind__truediv__(VM::tp_float, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__truediv__(VM::tp_float, [](VM* vm, PyVar _0, PyVar _1) {
         f64 value = CAST_F(_1);
         f64 value = CAST_F(_1);
         return VAR(_CAST(f64, _0) / value);
         return VAR(_CAST(f64, _0) / value);
     });
     });
-    _vm->bind__truediv__(VM::tp_int, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__truediv__(VM::tp_int, [](VM* vm, PyVar _0, PyVar _1) {
         f64 value = CAST_F(_1);
         f64 value = CAST_F(_1);
         return VAR(_CAST(i64, _0) / value);
         return VAR(_CAST(i64, _0) / value);
     });
     });
 
 
-    auto py_number_pow = [](VM* vm, PyObject* _0, PyObject* _1) {
+    auto py_number_pow = [](VM* vm, PyVar _0, PyVar _1) {
         i64 lhs, rhs;
         i64 lhs, rhs;
         if(try_cast_int(_0, &lhs) && try_cast_int(_1, &rhs)){
         if(try_cast_int(_0, &lhs) && try_cast_int(_1, &rhs)){
             if(rhs < 0) {
             if(rhs < 0) {
@@ -439,13 +439,13 @@ void __init_builtins(VM* _vm) {
         return VAR(val);
         return VAR(val);
     });
     });
 
 
-    _vm->bind__floordiv__(VM::tp_int, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__floordiv__(VM::tp_int, [](VM* vm, PyVar _0, PyVar _1) {
         i64 rhs = CAST(i64, _1);
         i64 rhs = CAST(i64, _1);
         if(rhs == 0) vm->ZeroDivisionError();
         if(rhs == 0) vm->ZeroDivisionError();
         return VAR(_CAST(i64, _0) / rhs);
         return VAR(_CAST(i64, _0) / rhs);
     });
     });
 
 
-    _vm->bind__mod__(VM::tp_int, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__mod__(VM::tp_int, [](VM* vm, PyVar _0, PyVar _1) {
         i64 rhs = CAST(i64, _1);
         i64 rhs = CAST(i64, _1);
         if(rhs == 0) vm->ZeroDivisionError();
         if(rhs == 0) vm->ZeroDivisionError();
         return VAR(_CAST(i64, _0) % rhs);
         return VAR(_CAST(i64, _0) % rhs);
@@ -459,15 +459,15 @@ void __init_builtins(VM* _vm) {
         return VAR(bits);
         return VAR(bits);
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_int, [](VM* vm, PyObject* obj) -> Str{
+    _vm->bind__repr__(VM::tp_int, [](VM* vm, PyVar obj) -> Str{
         return std::to_string(_CAST(i64, obj));
         return std::to_string(_CAST(i64, obj));
     });
     });
-    _vm->bind__neg__(VM::tp_int, [](VM* vm, PyObject* obj) { return VAR(-_CAST(i64, obj)); });
-    _vm->bind__hash__(VM::tp_int, [](VM* vm, PyObject* obj) { return _CAST(i64, obj); });
-    _vm->bind__invert__(VM::tp_int, [](VM* vm, PyObject* obj) { return VAR(~_CAST(i64, obj)); });
+    _vm->bind__neg__(VM::tp_int, [](VM* vm, PyVar obj) { return VAR(-_CAST(i64, obj)); });
+    _vm->bind__hash__(VM::tp_int, [](VM* vm, PyVar obj) { return _CAST(i64, obj); });
+    _vm->bind__invert__(VM::tp_int, [](VM* vm, PyVar obj) { return VAR(~_CAST(i64, obj)); });
 
 
 #define INT_BITWISE_OP(name, op) \
 #define INT_BITWISE_OP(name, op) \
-    _vm->bind##name(VM::tp_int, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
+    _vm->bind##name(VM::tp_int, [](VM* vm, PyVar lhs, PyVar rhs) { \
         return VAR(_CAST(i64, lhs) op CAST(i64, rhs)); \
         return VAR(_CAST(i64, lhs) op CAST(i64, rhs)); \
     });
     });
 
 
@@ -511,14 +511,14 @@ void __init_builtins(VM* _vm) {
         return VAR(float_out);
         return VAR(float_out);
     });
     });
 
 
-    _vm->bind__hash__(VM::tp_float, [](VM* vm, PyObject* _0) {
+    _vm->bind__hash__(VM::tp_float, [](VM* vm, PyVar _0) {
         f64 val = _CAST(f64, _0);
         f64 val = _CAST(f64, _0);
         return (i64)std::hash<f64>()(val);
         return (i64)std::hash<f64>()(val);
     });
     });
 
 
-    _vm->bind__neg__(VM::tp_float, [](VM* vm, PyObject* _0) { return VAR(-_CAST(f64, _0)); });
+    _vm->bind__neg__(VM::tp_float, [](VM* vm, PyVar _0) { return VAR(-_CAST(f64, _0)); });
 
 
-    _vm->bind__repr__(VM::tp_float, [](VM* vm, PyObject* _0) -> Str {
+    _vm->bind__repr__(VM::tp_float, [](VM* vm, PyVar _0) -> Str {
         f64 val = _CAST(f64, _0);
         f64 val = _CAST(f64, _0);
         SStream ss;
         SStream ss;
         ss << val;
         ss << val;
@@ -532,17 +532,17 @@ void __init_builtins(VM* _vm) {
         return VAR(vm->py_str(args[1]));
         return VAR(vm->py_str(args[1]));
     });
     });
 
 
-    _vm->bind__hash__(VM::tp_str, [](VM* vm, PyObject* _0) {
+    _vm->bind__hash__(VM::tp_str, [](VM* vm, PyVar _0) {
         return (i64)_CAST(Str&, _0).hash();
         return (i64)_CAST(Str&, _0).hash();
     });
     });
 
 
-    _vm->bind__add__(VM::tp_str, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__add__(VM::tp_str, [](VM* vm, PyVar _0, PyVar _1) {
         return VAR(_CAST(Str&, _0) + CAST(Str&, _1));
         return VAR(_CAST(Str&, _0) + CAST(Str&, _1));
     });
     });
-    _vm->bind__len__(VM::tp_str, [](VM* vm, PyObject* _0) {
+    _vm->bind__len__(VM::tp_str, [](VM* vm, PyVar _0) {
         return (i64)_CAST(Str&, _0).u8_length();
         return (i64)_CAST(Str&, _0).u8_length();
     });
     });
-    _vm->bind__mul__(VM::tp_str, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__mul__(VM::tp_str, [](VM* vm, PyVar _0, PyVar _1) {
         const Str& self = _CAST(Str&, _0);
         const Str& self = _CAST(Str&, _0);
         i64 n = CAST(i64, _1);
         i64 n = CAST(i64, _1);
         SStream ss;
         SStream ss;
@@ -556,20 +556,20 @@ void __init_builtins(VM* _vm) {
         for(i64 i = 0; i < n; i++) ss << self.sv();
         for(i64 i = 0; i < n; i++) ss << self.sv();
         return VAR(ss.str());
         return VAR(ss.str());
     });
     });
-    _vm->bind__contains__(VM::tp_str, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__contains__(VM::tp_str, [](VM* vm, PyVar _0, PyVar _1) {
         const Str& self = _CAST(Str&, _0);
         const Str& self = _CAST(Str&, _0);
         return VAR(self.index(CAST(Str&, _1)) != -1);
         return VAR(self.index(CAST(Str&, _1)) != -1);
     });
     });
 
 
     _vm->bind_func(VM::tp_str, __str__, 1, [](VM* vm, ArgsView args) { return args[0]; });
     _vm->bind_func(VM::tp_str, __str__, 1, [](VM* vm, ArgsView args) { return args[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) -> Str {
+    _vm->bind__iter__(VM::tp_str, [](VM* vm, PyVar _0) { return vm->new_user_object<StringIter>(_0); });
+    _vm->bind__repr__(VM::tp_str, [](VM* vm, PyVar _0) -> Str {
         const Str& self = _CAST(Str&, _0);
         const Str& self = _CAST(Str&, _0);
         return self.escape();
         return self.escape();
     });
     });
 
 
 #define BIND_CMP_STR(name, op) \
 #define BIND_CMP_STR(name, op) \
-    _vm->bind##name(VM::tp_str, [](VM* vm, PyObject* lhs, PyObject* rhs) { \
+    _vm->bind##name(VM::tp_str, [](VM* vm, PyVar lhs, PyVar rhs) { \
         if(!is_type(rhs, vm->tp_str)) return vm->NotImplemented; \
         if(!is_type(rhs, vm->tp_str)) return vm->NotImplemented; \
         return VAR(_CAST(Str&, lhs) op _CAST(Str&, rhs));                   \
         return VAR(_CAST(Str&, lhs) op _CAST(Str&, rhs));                   \
     });
     });
@@ -581,7 +581,7 @@ void __init_builtins(VM* _vm) {
     BIND_CMP_STR(__ge__, >=)
     BIND_CMP_STR(__ge__, >=)
 #undef BIND_CMP_STR
 #undef BIND_CMP_STR
 
 
-    _vm->bind__getitem__(VM::tp_str, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__getitem__(VM::tp_str, [](VM* vm, PyVar _0, PyVar _1) {
         const Str& self = PK_OBJ_GET(Str, _0);
         const Str& self = PK_OBJ_GET(Str, _0);
         if(is_type(_1, vm->tp_slice)){
         if(is_type(_1, vm->tp_slice)){
             const Slice& s = _CAST(Slice&, _1);
             const Slice& s = _CAST(Slice&, _1);
@@ -677,9 +677,9 @@ void __init_builtins(VM* _vm) {
         auto _lock = vm->heap.gc_scope_lock();
         auto _lock = vm->heap.gc_scope_lock();
         const Str& self = _CAST(Str&, args[0]);
         const Str& self = _CAST(Str&, args[0]);
         SStream ss;
         SStream ss;
-        PyObject* it = vm->py_iter(args[1]);     // strong ref
+        PyVar it = vm->py_iter(args[1]);     // strong ref
         const PyTypeInfo* info = vm->_tp_info(args[1]);
         const PyTypeInfo* info = vm->_tp_info(args[1]);
-        PyObject* obj = vm->_py_next(info, it);
+        PyVar obj = vm->_py_next(info, it);
         while(obj != vm->StopIteration){
         while(obj != vm->StopIteration){
             if(!ss.empty()) ss << self;
             if(!ss.empty()) ss << self;
             ss << CAST(Str&, obj);
             ss << CAST(Str&, obj);
@@ -771,13 +771,13 @@ void __init_builtins(VM* _vm) {
     // tp_list / tp_tuple
     // tp_list / tp_tuple
     _vm->bind(_vm->_t(VM::tp_list), "sort(self, key=None, reverse=False)", [](VM* vm, ArgsView args) {
     _vm->bind(_vm->_t(VM::tp_list), "sort(self, key=None, reverse=False)", [](VM* vm, ArgsView args) {
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
-        PyObject* key = args[1];
+        PyVar key = args[1];
         if(key == vm->None){
         if(key == vm->None){
-            std::stable_sort(self.begin(), self.end(), [vm](PyObject* a, PyObject* b){
+            std::stable_sort(self.begin(), self.end(), [vm](PyVar a, PyVar b){
                 return vm->py_lt(a, b);
                 return vm->py_lt(a, b);
             });
             });
         }else{
         }else{
-            std::stable_sort(self.begin(), self.end(), [vm, key](PyObject* a, PyObject* b){
+            std::stable_sort(self.begin(), self.end(), [vm, key](PyVar a, PyVar b){
                 return vm->py_lt(vm->call(key, a), vm->call(key, b));
                 return vm->py_lt(vm->call(key, a), vm->call(key, b));
             });
             });
         }
         }
@@ -786,7 +786,7 @@ void __init_builtins(VM* _vm) {
         return vm->None;
         return vm->None;
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_list, [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__repr__(VM::tp_list, [](VM* vm, PyVar _0) -> Str{
         if(vm->_repr_recursion_set.count(_0)) return "[...]";
         if(vm->_repr_recursion_set.count(_0)) return "[...]";
         List& iterable = _CAST(List&, _0);
         List& iterable = _CAST(List&, _0);
         SStream ss;
         SStream ss;
@@ -801,7 +801,7 @@ void __init_builtins(VM* _vm) {
         return ss.str();
         return ss.str();
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_tuple, [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__repr__(VM::tp_tuple, [](VM* vm, PyVar _0) -> Str{
         Tuple& iterable = _CAST(Tuple&, _0);
         Tuple& iterable = _CAST(Tuple&, _0);
         SStream ss;
         SStream ss;
         ss << '(';
         ss << '(';
@@ -825,20 +825,20 @@ void __init_builtins(VM* _vm) {
         return vm->None;
         return vm->None;
     });
     });
 
 
-    _vm->bind__contains__(VM::tp_list, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__contains__(VM::tp_list, [](VM* vm, PyVar _0, PyVar _1) {
         List& self = _CAST(List&, _0);
         List& self = _CAST(List&, _0);
-        for(PyObject* i: self) if(vm->py_eq(i, _1)) return vm->True;
+        for(PyVar i: self) if(vm->py_eq(i, _1)) return vm->True;
         return vm->False;
         return vm->False;
     });
     });
 
 
     _vm->bind_func(VM::tp_list, "count", 2, [](VM* vm, ArgsView args) {
     _vm->bind_func(VM::tp_list, "count", 2, [](VM* vm, ArgsView args) {
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
         int count = 0;
         int count = 0;
-        for(PyObject* i: self) if(vm->py_eq(i, args[1])) count++;
+        for(PyVar i: self) if(vm->py_eq(i, args[1])) count++;
         return VAR(count);
         return VAR(count);
     });
     });
 
 
-    _vm->bind__eq__(VM::tp_list, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__eq__(VM::tp_list, [](VM* vm, PyVar _0, PyVar _1) {
         List& a = _CAST(List&, _0);
         List& a = _CAST(List&, _0);
         if(!is_type(_1, vm->tp_list)) return vm->NotImplemented;
         if(!is_type(_1, vm->tp_list)) return vm->NotImplemented;
         List& b = _CAST(List&, _1);
         List& b = _CAST(List&, _1);
@@ -851,7 +851,7 @@ void __init_builtins(VM* _vm) {
 
 
     _vm->bind(_vm->_t(VM::tp_list), "index(self, value, __start=0)", [](VM* vm, ArgsView args) {
     _vm->bind(_vm->_t(VM::tp_list), "index(self, value, __start=0)", [](VM* vm, ArgsView args) {
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
-        PyObject* obj = args[1];
+        PyVar obj = args[1];
         int start = CAST(int, args[2]);
         int start = CAST(int, args[2]);
         for(int i=start; i<self.size(); i++){
         for(int i=start; i<self.size(); i++){
             if(vm->py_eq(self[i], obj)) return VAR(i);
             if(vm->py_eq(self[i], obj)) return VAR(i);
@@ -862,7 +862,7 @@ void __init_builtins(VM* _vm) {
 
 
     _vm->bind_func(VM::tp_list, "remove", 2, [](VM* vm, ArgsView args) {
     _vm->bind_func(VM::tp_list, "remove", 2, [](VM* vm, ArgsView args) {
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
-        PyObject* obj = args[1];
+        PyVar obj = args[1];
         for(int i=0; i<self.size(); i++){
         for(int i=0; i<self.size(); i++){
             if(vm->py_eq(self[i], obj)){
             if(vm->py_eq(self[i], obj)){
                 self.erase(i);
                 self.erase(i);
@@ -882,7 +882,7 @@ void __init_builtins(VM* _vm) {
         if(args.size() == 1+1){
         if(args.size() == 1+1){
             i64 index = CAST(i64, args[1]);
             i64 index = CAST(i64, args[1]);
             index = vm->normalized_index(index, self.size());
             index = vm->normalized_index(index, self.size());
-            PyObject* ret = self[index];
+            PyVar ret = self[index];
             self.erase(index);
             self.erase(index);
             return ret;
             return ret;
         }
         }
@@ -899,9 +899,9 @@ void __init_builtins(VM* _vm) {
     _vm->bind_func(VM::tp_list, "extend", 2, [](VM* vm, ArgsView args) {
     _vm->bind_func(VM::tp_list, "extend", 2, [](VM* vm, ArgsView args) {
         auto _lock = vm->heap.gc_scope_lock();
         auto _lock = vm->heap.gc_scope_lock();
         List& self = _CAST(List&, args[0]);
         List& self = _CAST(List&, args[0]);
-        PyObject* it = vm->py_iter(args[1]);     // strong ref
+        PyVar it = vm->py_iter(args[1]);     // strong ref
         const PyTypeInfo* info = vm->_tp_info(args[1]);
         const PyTypeInfo* info = vm->_tp_info(args[1]);
-        PyObject* obj = vm->_py_next(info, it);
+        PyVar obj = vm->_py_next(info, it);
         while(obj != vm->StopIteration){
         while(obj != vm->StopIteration){
             self.push_back(obj);
             self.push_back(obj);
             obj = vm->_py_next(info, it);
             obj = vm->_py_next(info, it);
@@ -915,7 +915,7 @@ void __init_builtins(VM* _vm) {
         return vm->None;
         return vm->None;
     });
     });
 
 
-    _vm->bind__mul__(VM::tp_list, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__mul__(VM::tp_list, [](VM* vm, PyVar _0, PyVar _1) {
         const List& self = _CAST(List&, _0);
         const List& self = _CAST(List&, _0);
         if(!is_int(_1)) return vm->NotImplemented;
         if(!is_int(_1)) return vm->NotImplemented;
         int n = _CAST(int, _1);
         int n = _CAST(int, _1);
@@ -952,7 +952,7 @@ void __init_builtins(VM* _vm) {
     _vm->bind_func(VM::tp_list, "copy", 1, PK_LAMBDA(VAR(_CAST(List, args[0]))));
     _vm->bind_func(VM::tp_list, "copy", 1, PK_LAMBDA(VAR(_CAST(List, args[0]))));
 
 
 #define BIND_RICH_CMP(name, op, _t, _T)    \
 #define BIND_RICH_CMP(name, op, _t, _T)    \
-    _vm->bind__##name##__(_vm->_t, [](VM* vm, PyObject* lhs, PyObject* rhs){        \
+    _vm->bind__##name##__(_vm->_t, [](VM* vm, PyVar lhs, PyVar rhs){        \
         if(!is_type(rhs, vm->_t)) return vm->NotImplemented;             \
         if(!is_type(rhs, vm->_t)) return vm->NotImplemented;             \
         auto& a = _CAST(_T&, lhs);                                                  \
         auto& a = _CAST(_T&, lhs);                                                  \
         auto& b = _CAST(_T&, rhs);                                                  \
         auto& b = _CAST(_T&, rhs);                                                  \
@@ -975,7 +975,7 @@ void __init_builtins(VM* _vm) {
 
 
 #undef BIND_RICH_CMP
 #undef BIND_RICH_CMP
 
 
-    _vm->bind__add__(VM::tp_list, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__add__(VM::tp_list, [](VM* vm, PyVar _0, PyVar _1) {
         const List& self = _CAST(List&, _0);
         const List& self = _CAST(List&, _0);
         const List& other = CAST(List&, _1);
         const List& other = CAST(List&, _1);
         List new_list(self);    // copy construct
         List new_list(self);    // copy construct
@@ -983,21 +983,21 @@ void __init_builtins(VM* _vm) {
         return VAR(std::move(new_list));
         return VAR(std::move(new_list));
     });
     });
 
 
-    _vm->bind__len__(VM::tp_list, [](VM* vm, PyObject* _0) {
+    _vm->bind__len__(VM::tp_list, [](VM* vm, PyVar _0) {
         return (i64)_CAST(List&, _0).size();
         return (i64)_CAST(List&, _0).size();
     });
     });
-    _vm->bind__iter__(VM::tp_list, [](VM* vm, PyObject* _0) {
+    _vm->bind__iter__(VM::tp_list, [](VM* vm, PyVar _0) {
         List& self = _CAST(List&, _0);
         List& self = _CAST(List&, _0);
         return vm->new_user_object<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, PyVar _0, PyVar _1, PyVar _2){
         List& self = _CAST(List&, _0);
         List& self = _CAST(List&, _0);
         i64 i = CAST(i64, _1);
         i64 i = CAST(i64, _1);
         i = vm->normalized_index(i, self.size());
         i = vm->normalized_index(i, self.size());
         self[i] = _2;
         self[i] = _2;
     });
     });
-    _vm->bind__delitem__(VM::tp_list, [](VM* vm, PyObject* _0, PyObject* _1){
+    _vm->bind__delitem__(VM::tp_list, [](VM* vm, PyVar _0, PyVar _1){
         List& self = _CAST(List&, _0);
         List& self = _CAST(List&, _0);
         i64 i = CAST(i64, _1);
         i64 i = CAST(i64, _1);
         i = vm->normalized_index(i, self.size());
         i = vm->normalized_index(i, self.size());
@@ -1014,20 +1014,20 @@ void __init_builtins(VM* _vm) {
         return vm->None;
         return vm->None;
     });
     });
 
 
-    _vm->bind__contains__(VM::tp_tuple, [](VM* vm, PyObject* obj, PyObject* item) {
+    _vm->bind__contains__(VM::tp_tuple, [](VM* vm, PyVar obj, PyVar item) {
         Tuple& self = _CAST(Tuple&, obj);
         Tuple& self = _CAST(Tuple&, obj);
-        for(PyObject* i: self) if(vm->py_eq(i, item)) return vm->True;
+        for(PyVar i: self) if(vm->py_eq(i, item)) return vm->True;
         return vm->False;
         return vm->False;
     });
     });
 
 
     _vm->bind_func(VM::tp_tuple, "count", 2, [](VM* vm, ArgsView args) {
     _vm->bind_func(VM::tp_tuple, "count", 2, [](VM* vm, ArgsView args) {
         Tuple& self = _CAST(Tuple&, args[0]);
         Tuple& self = _CAST(Tuple&, args[0]);
         int count = 0;
         int count = 0;
-        for(PyObject* i: self) if(vm->py_eq(i, args[1])) count++;
+        for(PyVar i: self) if(vm->py_eq(i, args[1])) count++;
         return VAR(count);
         return VAR(count);
     });
     });
 
 
-    _vm->bind__eq__(VM::tp_tuple, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__eq__(VM::tp_tuple, [](VM* vm, PyVar _0, PyVar _1) {
         const Tuple& self = _CAST(Tuple&, _0);
         const Tuple& self = _CAST(Tuple&, _0);
         if(!is_type(_1, vm->tp_tuple)) return vm->NotImplemented;
         if(!is_type(_1, vm->tp_tuple)) return vm->NotImplemented;
         const Tuple& other = _CAST(Tuple&, _1);
         const Tuple& other = _CAST(Tuple&, _1);
@@ -1038,9 +1038,9 @@ void __init_builtins(VM* _vm) {
         return vm->True;
         return vm->True;
     });
     });
 
 
-    _vm->bind__hash__(VM::tp_tuple, [](VM* vm, PyObject* _0) {
+    _vm->bind__hash__(VM::tp_tuple, [](VM* vm, PyVar _0) {
         i64 x = 1000003;
         i64 x = 1000003;
-        for (PyObject* item: _CAST(Tuple&, _0)) {
+        for (PyVar item: _CAST(Tuple&, _0)) {
             i64 y = vm->py_hash(item);
             i64 y = vm->py_hash(item);
             // recommended by Github Copilot
             // recommended by Github Copilot
             x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2));
             x = x ^ (y + 0x9e3779b9 + (x << 6) + (x >> 2));
@@ -1048,45 +1048,45 @@ void __init_builtins(VM* _vm) {
         return x;
         return x;
     });
     });
 
 
-    _vm->bind__iter__(VM::tp_tuple, [](VM* vm, PyObject* _0) {
+    _vm->bind__iter__(VM::tp_tuple, [](VM* vm, PyVar _0) {
         Tuple& self = _CAST(Tuple&, _0);
         Tuple& self = _CAST(Tuple&, _0);
         return vm->new_user_object<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, PyVar obj) {
         return (i64)_CAST(Tuple&, obj).size();
         return (i64)_CAST(Tuple&, obj).size();
     });
     });
 
 
     // tp_bool
     // tp_bool
     _vm->bind_func(VM::tp_bool, __new__, 2, PK_LAMBDA(VAR(vm->py_bool(args[1]))));
     _vm->bind_func(VM::tp_bool, __new__, 2, PK_LAMBDA(VAR(vm->py_bool(args[1]))));
-    _vm->bind__hash__(VM::tp_bool, [](VM* vm, PyObject* _0) {
+    _vm->bind__hash__(VM::tp_bool, [](VM* vm, PyVar _0) {
         return (i64)_CAST(bool, _0);
         return (i64)_CAST(bool, _0);
     });
     });
-    _vm->bind__repr__(VM::tp_bool, [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__repr__(VM::tp_bool, [](VM* vm, PyVar _0) -> Str{
         bool val = _CAST(bool, _0);
         bool val = _CAST(bool, _0);
         return val ? "True" : "False";
         return val ? "True" : "False";
     });
     });
 
 
-    _vm->bind__and__(VM::tp_bool, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__and__(VM::tp_bool, [](VM* vm, PyVar _0, PyVar _1) {
         return VAR(_CAST(bool, _0) && CAST(bool, _1));
         return VAR(_CAST(bool, _0) && CAST(bool, _1));
     });
     });
-    _vm->bind__or__(VM::tp_bool, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__or__(VM::tp_bool, [](VM* vm, PyVar _0, PyVar _1) {
         return VAR(_CAST(bool, _0) || CAST(bool, _1));
         return VAR(_CAST(bool, _0) || CAST(bool, _1));
     });
     });
-    _vm->bind__xor__(VM::tp_bool, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__xor__(VM::tp_bool, [](VM* vm, PyVar _0, PyVar _1) {
         return VAR(_CAST(bool, _0) != CAST(bool, _1));
         return VAR(_CAST(bool, _0) != CAST(bool, _1));
     });
     });
-    _vm->bind__eq__(VM::tp_bool, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__eq__(VM::tp_bool, [](VM* vm, PyVar _0, PyVar _1) {
         if(is_type(_1, vm->tp_bool)) return VAR(_0 == _1);
         if(is_type(_1, vm->tp_bool)) return VAR(_0 == _1);
         if(is_int(_1)) return VAR(_CAST(bool, _0) == (bool)CAST(i64, _1));
         if(is_int(_1)) return VAR(_CAST(bool, _0) == (bool)CAST(i64, _1));
         return vm->NotImplemented;
         return vm->NotImplemented;
     });
     });
 
 
     // tp_ellipsis / tp_NotImplementedType
     // tp_ellipsis / tp_NotImplementedType
-    _vm->bind__repr__(_vm->_tp(_vm->Ellipsis), [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__repr__(_vm->_tp(_vm->Ellipsis), [](VM* vm, PyVar _0) -> Str{
         return "...";
         return "...";
     });
     });
-    _vm->bind__repr__(_vm->_tp(_vm->NotImplemented), [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__repr__(_vm->_tp(_vm->NotImplemented), [](VM* vm, PyVar _0) -> Str{
         return "NotImplemented";
         return "NotImplemented";
     });
     });
 
 
@@ -1102,7 +1102,7 @@ void __init_builtins(VM* _vm) {
         return VAR(Bytes(buffer, list.size()));
         return VAR(Bytes(buffer, list.size()));
     });
     });
 
 
-    _vm->bind__getitem__(VM::tp_bytes, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__getitem__(VM::tp_bytes, [](VM* vm, PyVar _0, PyVar _1) {
         const Bytes& self = PK_OBJ_GET(Bytes, _0);
         const Bytes& self = PK_OBJ_GET(Bytes, _0);
         if(is_type(_1, vm->tp_slice)){
         if(is_type(_1, vm->tp_slice)){
             const Slice& s = _CAST(Slice&, _1);
             const Slice& s = _CAST(Slice&, _1);
@@ -1120,7 +1120,7 @@ void __init_builtins(VM* _vm) {
         return VAR(self[i]);
         return VAR(self[i]);
     });
     });
 
 
-    _vm->bind__add__(VM::tp_bytes, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__add__(VM::tp_bytes, [](VM* vm, PyVar _0, PyVar _1) {
         const Bytes& a = _CAST(Bytes&, _0);
         const Bytes& a = _CAST(Bytes&, _0);
         const Bytes& b = CAST(Bytes&, _1);
         const Bytes& b = CAST(Bytes&, _1);
         unsigned char *buffer = new unsigned char[a.size() + b.size()];
         unsigned char *buffer = new unsigned char[a.size() + b.size()];
@@ -1129,13 +1129,13 @@ void __init_builtins(VM* _vm) {
         return VAR(Bytes(buffer, a.size() + b.size()));
         return VAR(Bytes(buffer, a.size() + b.size()));
     });
     });
 
 
-    _vm->bind__hash__(VM::tp_bytes, [](VM* vm, PyObject* _0) {
+    _vm->bind__hash__(VM::tp_bytes, [](VM* vm, PyVar _0) {
         const Bytes& self = _CAST(Bytes&, _0);
         const Bytes& self = _CAST(Bytes&, _0);
         std::string_view view((char*)self.data(), self.size());
         std::string_view view((char*)self.data(), self.size());
         return (i64)std::hash<std::string_view>()(view);
         return (i64)std::hash<std::string_view>()(view);
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_bytes, [](VM* vm, PyObject* _0) -> Str {
+    _vm->bind__repr__(VM::tp_bytes, [](VM* vm, PyVar _0) -> Str {
         const Bytes& self = _CAST(Bytes&, _0);
         const Bytes& self = _CAST(Bytes&, _0);
         SStream ss;
         SStream ss;
         ss << "b'";
         ss << "b'";
@@ -1146,7 +1146,7 @@ void __init_builtins(VM* _vm) {
         ss << "'";
         ss << "'";
         return ss.str();
         return ss.str();
     });
     });
-    _vm->bind__len__(VM::tp_bytes, [](VM* vm, PyObject* _0) {
+    _vm->bind__len__(VM::tp_bytes, [](VM* vm, PyVar _0) {
         return (i64)_CAST(Bytes&, _0).size();
         return (i64)_CAST(Bytes&, _0).size();
     });
     });
 
 
@@ -1156,7 +1156,7 @@ void __init_builtins(VM* _vm) {
         return VAR(Str(self.str()));
         return VAR(Str(self.str()));
     });
     });
 
 
-    _vm->bind__eq__(VM::tp_bytes, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__eq__(VM::tp_bytes, [](VM* vm, PyVar _0, PyVar _1) {
         if(!is_type(_1, vm->tp_bytes)) return vm->NotImplemented;
         if(!is_type(_1, vm->tp_bytes)) return vm->NotImplemented;
         return VAR(_CAST(Bytes&, _0) == _CAST(Bytes&, _1));
         return VAR(_CAST(Bytes&, _0) == _CAST(Bytes&, _1));
     });
     });
@@ -1166,7 +1166,7 @@ void __init_builtins(VM* _vm) {
         return VAR(Slice(args[1], args[2], args[3]));
         return VAR(Slice(args[1], args[2], args[3]));
     });
     });
 
 
-    _vm->bind__eq__(VM::tp_slice, [](VM* vm, PyObject* _0, PyObject* _1){
+    _vm->bind__eq__(VM::tp_slice, [](VM* vm, PyVar _0, PyVar _1){
         const Slice& self = _CAST(Slice&, _0);
         const Slice& self = _CAST(Slice&, _0);
         if(!is_type(_1, vm->tp_slice)) return vm->NotImplemented;
         if(!is_type(_1, vm->tp_slice)) return vm->NotImplemented;
         const Slice& other = _CAST(Slice&, _1);
         const Slice& other = _CAST(Slice&, _1);
@@ -1176,7 +1176,7 @@ void __init_builtins(VM* _vm) {
         return vm->True;
         return vm->True;
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_slice, [](VM* vm, PyObject* _0) -> Str {
+    _vm->bind__repr__(VM::tp_slice, [](VM* vm, PyVar _0) -> Str {
         const Slice& self = _CAST(Slice&, _0);
         const Slice& self = _CAST(Slice&, _0);
         SStream ss;
         SStream ss;
         ss << "slice(";
         ss << "slice(";
@@ -1205,27 +1205,27 @@ void __init_builtins(VM* _vm) {
         MappingProxy& self = _CAST(MappingProxy&, args[0]);
         MappingProxy& self = _CAST(MappingProxy&, args[0]);
         List items;
         List items;
         for(auto [k, v] : self.attr().items()){
         for(auto [k, v] : self.attr().items()){
-            PyObject* t = VAR(Tuple(VAR(k.sv()), v));
+            PyVar t = VAR(Tuple(VAR(k.sv()), v));
             items.push_back(std::move(t));
             items.push_back(std::move(t));
         }
         }
         return VAR(std::move(items));
         return VAR(std::move(items));
     });
     });
 
 
-    _vm->bind__len__(VM::tp_mappingproxy, [](VM* vm, PyObject* _0) {
+    _vm->bind__len__(VM::tp_mappingproxy, [](VM* vm, PyVar _0) {
         return (i64)_CAST(MappingProxy&, _0).attr().size();
         return (i64)_CAST(MappingProxy&, _0).attr().size();
     });
     });
 
 
-    _vm->bind__eq__(VM::tp_mappingproxy, [](VM* vm, PyObject* _0, PyObject* _1){
+    _vm->bind__eq__(VM::tp_mappingproxy, [](VM* vm, PyVar _0, PyVar _1){
         const MappingProxy& a = _CAST(MappingProxy&, _0);
         const MappingProxy& a = _CAST(MappingProxy&, _0);
         if(!is_type(_1, VM::tp_mappingproxy)) return vm->NotImplemented;
         if(!is_type(_1, VM::tp_mappingproxy)) return vm->NotImplemented;
         const MappingProxy& b = _CAST(MappingProxy&, _1);
         const MappingProxy& b = _CAST(MappingProxy&, _1);
         return VAR(a.obj == b.obj);
         return VAR(a.obj == b.obj);
     });
     });
 
 
-    _vm->bind__getitem__(VM::tp_mappingproxy, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__getitem__(VM::tp_mappingproxy, [](VM* vm, PyVar _0, PyVar _1) {
         MappingProxy& self = _CAST(MappingProxy&, _0);
         MappingProxy& self = _CAST(MappingProxy&, _0);
         StrName key = CAST(Str&, _1);
         StrName key = CAST(Str&, _1);
-        PyObject* ret = self.attr().try_get_likely_found(key);
+        PyVar ret = self.attr().try_get_likely_found(key);
         if(ret == nullptr) vm->KeyError(_1);
         if(ret == nullptr) vm->KeyError(_1);
         return ret;
         return ret;
     });
     });
@@ -1233,12 +1233,12 @@ void __init_builtins(VM* _vm) {
     _vm->bind(_vm->_t(VM::tp_mappingproxy), "get(self, key, default=None)", [](VM* vm, ArgsView args) {
     _vm->bind(_vm->_t(VM::tp_mappingproxy), "get(self, key, default=None)", [](VM* vm, ArgsView args) {
         MappingProxy& self = _CAST(MappingProxy&, args[0]);
         MappingProxy& self = _CAST(MappingProxy&, args[0]);
         StrName key = CAST(Str&, args[1]);
         StrName key = CAST(Str&, args[1]);
-        PyObject* ret = self.attr().try_get(key);
+        PyVar ret = self.attr().try_get(key);
         if(ret == nullptr) return args[2];
         if(ret == nullptr) return args[2];
         return ret;
         return ret;
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_mappingproxy, [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__repr__(VM::tp_mappingproxy, [](VM* vm, PyVar _0) -> Str{
         if(vm->_repr_recursion_set.count(_0)) return "{...}";
         if(vm->_repr_recursion_set.count(_0)) return "{...}";
         MappingProxy& self = _CAST(MappingProxy&, _0);
         MappingProxy& self = _CAST(MappingProxy&, _0);
         SStream ss;
         SStream ss;
@@ -1256,7 +1256,7 @@ void __init_builtins(VM* _vm) {
         return ss.str();
         return ss.str();
     });
     });
 
 
-    _vm->bind__contains__(VM::tp_mappingproxy, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__contains__(VM::tp_mappingproxy, [](VM* vm, PyVar _0, PyVar _1) {
         MappingProxy& self = _CAST(MappingProxy&, _0);
         MappingProxy& self = _CAST(MappingProxy&, _0);
         return VAR(self.attr().contains(CAST(Str&, _1)));
         return VAR(self.attr().contains(CAST(Str&, _1)));
     });
     });
@@ -1279,7 +1279,7 @@ void __init_builtins(VM* _vm) {
             }
             }
             if(is_type(args[1], vm->tp_list)){
             if(is_type(args[1], vm->tp_list)){
                 List& list = PK_OBJ_GET(List, args[1]);
                 List& list = PK_OBJ_GET(List, args[1]);
-                for(PyObject* item : list){
+                for(PyVar item : list){
                     Tuple& t = CAST(Tuple&, item);
                     Tuple& t = CAST(Tuple&, item);
                     if(t.size() != 2){
                     if(t.size() != 2){
                         vm->ValueError("dict() takes a list of tuples (key, value)");
                         vm->ValueError("dict() takes a list of tuples (key, value)");
@@ -1295,17 +1295,17 @@ void __init_builtins(VM* _vm) {
         PK_UNREACHABLE()
         PK_UNREACHABLE()
     });
     });
 
 
-    _vm->bind__len__(VM::tp_dict, [](VM* vm, PyObject* _0) {
+    _vm->bind__len__(VM::tp_dict, [](VM* vm, PyVar _0) {
         return (i64)PK_OBJ_GET(Dict, _0).size();
         return (i64)PK_OBJ_GET(Dict, _0).size();
     });
     });
 
 
-    _vm->bind__getitem__(VM::tp_dict, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__getitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
         Dict& self = PK_OBJ_GET(Dict, _0);
         Dict& self = PK_OBJ_GET(Dict, _0);
-        PyObject* ret = self.try_get(_1);
+        PyVar ret = self.try_get(_1);
         if(ret == nullptr){
         if(ret == nullptr){
             // try __missing__
             // try __missing__
-            PyObject* self;
-            PyObject* f_missing = vm->get_unbound_method(_0, __missing__, &self, false);
+            PyVar self;
+            PyVar f_missing = vm->get_unbound_method(_0, __missing__, &self, false);
             if(f_missing != nullptr){
             if(f_missing != nullptr){
                 return vm->call_method(self, f_missing, _1);
                 return vm->call_method(self, f_missing, _1);
             }
             }
@@ -1314,12 +1314,12 @@ void __init_builtins(VM* _vm) {
         return ret;
         return ret;
     });
     });
 
 
-    _vm->bind__setitem__(VM::tp_dict, [](VM* vm, PyObject* _0, PyObject* _1, PyObject* _2) {
+    _vm->bind__setitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1, PyVar _2) {
         Dict& self = _CAST(Dict&, _0);
         Dict& self = _CAST(Dict&, _0);
         self.set(_1, _2);
         self.set(_1, _2);
     });
     });
 
 
-    _vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__delitem__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
         Dict& self = _CAST(Dict&, _0);
         Dict& self = _CAST(Dict&, _0);
         bool ok = self.erase(_1);
         bool ok = self.erase(_1);
         if(!ok) vm->KeyError(_1);
         if(!ok) vm->KeyError(_1);
@@ -1331,7 +1331,7 @@ void __init_builtins(VM* _vm) {
             return vm->None;
             return vm->None;
         }
         }
         Dict& self = _CAST(Dict&, args[0]);
         Dict& self = _CAST(Dict&, args[0]);
-        PyObject* value = self.try_get(args[1]);
+        PyVar value = self.try_get(args[1]);
         if(value == nullptr){
         if(value == nullptr){
             if(args.size() == 2) vm->KeyError(args[1]);
             if(args.size() == 2) vm->KeyError(args[1]);
             if(args.size() == 3){
             if(args.size() == 3){
@@ -1342,12 +1342,12 @@ void __init_builtins(VM* _vm) {
         return value;
         return value;
     });
     });
 
 
-    _vm->bind__contains__(VM::tp_dict, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__contains__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
         Dict& self = _CAST(Dict&, _0);
         Dict& self = _CAST(Dict&, _0);
         return VAR(self.contains(_1));
         return VAR(self.contains(_1));
     });
     });
 
 
-    _vm->bind__iter__(VM::tp_dict, [](VM* vm, PyObject* _0) {
+    _vm->bind__iter__(VM::tp_dict, [](VM* vm, PyVar _0) {
         const Dict& self = _CAST(Dict&, _0);
         const Dict& self = _CAST(Dict&, _0);
         return vm->py_iter(VAR(self.keys()));
         return vm->py_iter(VAR(self.keys()));
     });
     });
@@ -1355,11 +1355,11 @@ void __init_builtins(VM* _vm) {
     _vm->bind_func(VM::tp_dict, "get", -1, [](VM* vm, ArgsView args) {
     _vm->bind_func(VM::tp_dict, "get", -1, [](VM* vm, ArgsView args) {
         Dict& self = _CAST(Dict&, args[0]);
         Dict& self = _CAST(Dict&, args[0]);
         if(args.size() == 1+1){
         if(args.size() == 1+1){
-            PyObject* ret = self.try_get(args[1]);
+            PyVar ret = self.try_get(args[1]);
             if(ret != nullptr) return ret;
             if(ret != nullptr) return ret;
             return vm->None;
             return vm->None;
         }else if(args.size() == 1+2){
         }else if(args.size() == 1+2){
-            PyObject* ret = self.try_get(args[1]);
+            PyVar ret = self.try_get(args[1]);
             if(ret != nullptr) return ret;
             if(ret != nullptr) return ret;
             return args[2];
             return args[2];
         }
         }
@@ -1399,14 +1399,14 @@ void __init_builtins(VM* _vm) {
         return vm->None;
         return vm->None;
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_dict, [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__repr__(VM::tp_dict, [](VM* vm, PyVar _0) -> Str{
         if(vm->_repr_recursion_set.count(_0)) return "{...}";
         if(vm->_repr_recursion_set.count(_0)) return "{...}";
         Dict& self = _CAST(Dict&, _0);
         Dict& self = _CAST(Dict&, _0);
         SStream ss;
         SStream ss;
         ss << "{";
         ss << "{";
         bool first = true;
         bool first = true;
         vm->_repr_recursion_set.insert(_0);
         vm->_repr_recursion_set.insert(_0);
-        self.apply([&](PyObject* k, PyObject* v){
+        self.apply([&](PyVar k, PyVar v){
             if(!first) ss << ", ";
             if(!first) ss << ", ";
             first = false;
             first = false;
             ss << vm->py_repr(k) << ": " << vm->py_repr(v);
             ss << vm->py_repr(k) << ": " << vm->py_repr(v);
@@ -1416,7 +1416,7 @@ void __init_builtins(VM* _vm) {
         return ss.str();
         return ss.str();
     });
     });
 
 
-    _vm->bind__eq__(VM::tp_dict, [](VM* vm, PyObject* _0, PyObject* _1) {
+    _vm->bind__eq__(VM::tp_dict, [](VM* vm, PyVar _0, PyVar _1) {
         Dict& self = _CAST(Dict&, _0);
         Dict& self = _CAST(Dict&, _0);
         if(!vm->isinstance(_1, vm->tp_dict)) return vm->NotImplemented;
         if(!vm->isinstance(_1, vm->tp_dict)) return vm->NotImplemented;
         Dict& other = _CAST(Dict&, _1);
         Dict& other = _CAST(Dict&, _1);
@@ -1424,14 +1424,14 @@ void __init_builtins(VM* _vm) {
         for(int i=0; i<self._capacity; i++){
         for(int i=0; i<self._capacity; i++){
             auto item = self._items[i];
             auto item = self._items[i];
             if(item.first == nullptr) continue;
             if(item.first == nullptr) continue;
-            PyObject* value = other.try_get(item.first);
+            PyVar value = other.try_get(item.first);
             if(value == nullptr) return vm->False;
             if(value == nullptr) return vm->False;
             if(!vm->py_eq(item.second, value)) return vm->False;
             if(!vm->py_eq(item.second, value)) return vm->False;
         }
         }
         return vm->True;
         return vm->True;
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_module, [](VM* vm, PyObject* _0) -> Str {
+    _vm->bind__repr__(VM::tp_module, [](VM* vm, PyVar _0) -> Str {
         const Str& path = CAST(Str&, _0->attr(__path__));
         const Str& path = CAST(Str&, _0->attr(__path__));
         return _S("<module ", path.escape(), ">");
         return _S("<module ", path.escape(), ">");
     });
     });
@@ -1464,7 +1464,7 @@ void __init_builtins(VM* _vm) {
     _vm->bind_func(VM::tp_exception, __new__, -1, [](VM* vm, ArgsView args){
     _vm->bind_func(VM::tp_exception, __new__, -1, [](VM* vm, ArgsView args){
         Type cls = PK_OBJ_GET(Type, args[0]);
         Type cls = PK_OBJ_GET(Type, args[0]);
         StrName cls_name = _type_name(vm, cls);
         StrName cls_name = _type_name(vm, cls);
-        PyObject* e_obj = vm->heap.gcnew<Exception>(cls, cls_name);
+        PyVar e_obj = vm->heap.gcnew<Exception>(cls, cls_name);
         e_obj->_enable_instance_dict();
         e_obj->_enable_instance_dict();
         PK_OBJ_GET(Exception, e_obj)._self = e_obj;
         PK_OBJ_GET(Exception, e_obj)._self = e_obj;
         return e_obj;
         return e_obj;
@@ -1480,12 +1480,12 @@ void __init_builtins(VM* _vm) {
         return vm->None;
         return vm->None;
     });
     });
 
 
-    _vm->bind__repr__(VM::tp_exception, [](VM* vm, PyObject* _0) -> Str {
+    _vm->bind__repr__(VM::tp_exception, [](VM* vm, PyVar _0) -> Str {
         Exception& self = _CAST(Exception&, _0);
         Exception& self = _CAST(Exception&, _0);
         return _S(_type_name(vm, _0->type), '(', self.msg.escape(), ')');
         return _S(_type_name(vm, _0->type), '(', self.msg.escape(), ')');
     });
     });
 
 
-    _vm->bind__str__(VM::tp_exception, [](VM* vm, PyObject* _0) -> Str{
+    _vm->bind__str__(VM::tp_exception, [](VM* vm, PyVar _0) -> Str{
         Exception& self = _CAST(Exception&, _0);
         Exception& self = _CAST(Exception&, _0);
         return self.msg;
         return self.msg;
     });
     });
@@ -1502,7 +1502,7 @@ void VM::__post_init_builtin_types(){
 
 
     bind_func(tp_module, __new__, -1, PK_ACTION(vm->NotImplementedError()));
     bind_func(tp_module, __new__, -1, PK_ACTION(vm->NotImplementedError()));
 
 
-    _all_types[tp_module].m__getattr__ = [](VM* vm, PyObject* obj, StrName name) -> PyObject*{
+    _all_types[tp_module].m__getattr__ = [](VM* vm, PyVar obj, StrName name) -> PyVar{
         const Str& path = CAST(Str&, obj->attr(__path__));
         const Str& path = CAST(Str&, obj->attr(__path__));
         return vm->py_import(_S(path, ".", name.sv()), false);
         return vm->py_import(_S(path, ".", name.sv()), false);
     };
     };
@@ -1516,11 +1516,11 @@ void VM::__post_init_builtin_types(){
     });
     });
 
 
     // type
     // type
-    bind__getitem__(tp_type, [](VM* vm, PyObject* self, PyObject* _){
+    bind__getitem__(tp_type, [](VM* vm, PyVar self, PyVar _){
         return self;        // for generics
         return self;        // for generics
     });
     });
 
 
-    bind__repr__(tp_type, [](VM* vm, PyObject* self) -> Str{
+    bind__repr__(tp_type, [](VM* vm, PyVar self) -> Str{
         SStream ss;
         SStream ss;
         const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, self)];
         const PyTypeInfo& info = vm->_all_types[PK_OBJ_GET(Type, self)];
         ss << "<class '" << info.name << "'>";
         ss << "<class '" << info.name << "'>";
@@ -1548,7 +1548,7 @@ void VM::__post_init_builtin_types(){
         return CAST(BoundMethod&, args[0]).func;
         return CAST(BoundMethod&, args[0]).func;
     });
     });
 
 
-    bind__eq__(tp_bound_method, [](VM* vm, PyObject* lhs, PyObject* rhs){
+    bind__eq__(tp_bound_method, [](VM* vm, PyVar lhs, PyVar rhs){
         if(!is_type(rhs, vm->tp_bound_method)) return vm->NotImplemented;
         if(!is_type(rhs, vm->tp_bound_method)) return vm->NotImplemented;
         const BoundMethod& _0 = PK_OBJ_GET(BoundMethod, lhs);
         const BoundMethod& _0 = PK_OBJ_GET(BoundMethod, lhs);
         const BoundMethod& _1 = PK_OBJ_GET(BoundMethod, rhs);
         const BoundMethod& _1 = PK_OBJ_GET(BoundMethod, rhs);

+ 40 - 40
src/pocketpy_c.cpp

@@ -25,9 +25,9 @@ static int count_extra_elements(VM* vm, int n){
     return vm->s_data._sp - vm->__c.s_view.top().end();
     return vm->s_data._sp - vm->__c.s_view.top().end();
 }
 }
 
 
-static PyObject* stack_item(VM* vm, int index){
-    PyObject** begin;
-    PyObject** end = vm->s_data.end();
+static PyVar stack_item(VM* vm, int index){
+    PyVar* begin;
+    PyVar* end = vm->s_data.end();
     if(vm->callstack.empty()){
     if(vm->callstack.empty()){
         begin = vm->s_data.begin();
         begin = vm->s_data.begin();
     }else{
     }else{
@@ -48,7 +48,7 @@ static PyObject* stack_item(VM* vm, int index){
         vm->__c.error = e.self(); \
         vm->__c.error = e.self(); \
         return false; \
         return false; \
     } catch(const std::exception& re){ \
     } catch(const std::exception& re){ \
-        PyObject* e_t = vm->_t(vm->tp_exception); \
+        PyVar e_t = vm->_t(vm->tp_exception); \
         vm->__c.error = vm->call(e_t, VAR(re.what())); \
         vm->__c.error = vm->call(e_t, VAR(re.what())); \
         return false; \
         return false; \
     }
     }
@@ -64,7 +64,7 @@ void pkpy_delete_vm(pkpy_vm* vm){
 bool pkpy_exec(pkpy_vm* vm_handle, const char* source) {
 bool pkpy_exec(pkpy_vm* vm_handle, const char* source) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* res;
+    PyVar res;
     PK_PROTECTED(
     PK_PROTECTED(
         CodeObject_ code = vm->compile(source, "main.py", EXEC_MODE);
         CodeObject_ code = vm->compile(source, "main.py", EXEC_MODE);
         res = vm->_exec(code, vm->_main);
         res = vm->_exec(code, vm->_main);
@@ -75,8 +75,8 @@ bool pkpy_exec(pkpy_vm* vm_handle, const char* source) {
 bool pkpy_exec_2(pkpy_vm* vm_handle, const char* source, const char* filename, int mode, const char* module){
 bool pkpy_exec_2(pkpy_vm* vm_handle, const char* source, const char* filename, int mode, const char* module){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* res;
-    PyObject* mod;
+    PyVar res;
+    PyVar mod;
     PK_PROTECTED(
     PK_PROTECTED(
         if(module == nullptr){
         if(module == nullptr){
             mod = vm->_main;
             mod = vm->_main;
@@ -98,7 +98,7 @@ bool pkpy_dup(pkpy_vm* vm_handle, int n){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, n);
+        PyVar item = stack_item(vm, n);
         vm->s_data.push(item);
         vm->s_data.push(item);
     )
     )
     return true;
     return true;
@@ -150,7 +150,7 @@ int pkpy_stack_size(pkpy_vm* vm_handle){
 bool pkpy_push_int(pkpy_vm* vm_handle, int value) {
 bool pkpy_push_int(pkpy_vm* vm_handle, int value) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* res;
+    PyVar res;
     PK_PROTECTED(
     PK_PROTECTED(
         // int may overflow so we should protect it
         // int may overflow so we should protect it
         res = py_var(vm, value);
         res = py_var(vm, value);
@@ -171,7 +171,7 @@ bool pkpy_to_int(pkpy_vm* vm_handle, int i, int* out){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         *out = py_cast<int>(vm, item);
         *out = py_cast<int>(vm, item);
     )
     )
     return true;
     return true;
@@ -181,7 +181,7 @@ bool pkpy_to_int(pkpy_vm* vm_handle, int i, int* out){
 bool pkpy_push_float(pkpy_vm* vm_handle, double value) {
 bool pkpy_push_float(pkpy_vm* vm_handle, double value) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* res = py_var(vm, value);
+    PyVar res = py_var(vm, value);
     vm->s_data.push(res);
     vm->s_data.push(res);
     return true;
     return true;
 }
 }
@@ -190,7 +190,7 @@ bool pkpy_is_float(pkpy_vm* vm_handle, int i){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         return is_float(item);
         return is_float(item);
     )
     )
 }
 }
@@ -199,7 +199,7 @@ bool pkpy_to_float(pkpy_vm* vm_handle, int i, double* out){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         *out = py_cast<double>(vm, item);
         *out = py_cast<double>(vm, item);
     )
     )
     return true;
     return true;
@@ -217,7 +217,7 @@ bool pkpy_is_bool(pkpy_vm* vm_handle, int i){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         return is_type(item, vm->tp_bool);
         return is_type(item, vm->tp_bool);
     )
     )
 }
 }
@@ -226,7 +226,7 @@ bool pkpy_to_bool(pkpy_vm* vm_handle, int i, bool* out){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         *out = py_cast<bool>(vm, item);
         *out = py_cast<bool>(vm, item);
     )
     )
     return true;
     return true;
@@ -236,7 +236,7 @@ bool pkpy_to_bool(pkpy_vm* vm_handle, int i, bool* out){
 bool pkpy_push_string(pkpy_vm* vm_handle, pkpy_CString value) {
 bool pkpy_push_string(pkpy_vm* vm_handle, pkpy_CString value) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* res = py_var(vm, value);
+    PyVar res = py_var(vm, value);
     vm->s_data.push(res);
     vm->s_data.push(res);
     return true;
     return true;
 }
 }
@@ -245,7 +245,7 @@ bool pkpy_is_string(pkpy_vm* vm_handle, int i){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         return is_type(item, vm->tp_str);
         return is_type(item, vm->tp_str);
     )
     )
 }
 }
@@ -254,7 +254,7 @@ bool pkpy_to_string(pkpy_vm* vm_handle, int i, pkpy_CString* out){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         const Str& s = py_cast<Str&>(vm, item);
         const Str& s = py_cast<Str&>(vm, item);
         *out = s.c_str();
         *out = s.c_str();
     )
     )
@@ -265,7 +265,7 @@ bool pkpy_to_string(pkpy_vm* vm_handle, int i, pkpy_CString* out){
 bool pkpy_push_voidp(pkpy_vm* vm_handle, void* value) {
 bool pkpy_push_voidp(pkpy_vm* vm_handle, void* value) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* res = py_var(vm, value);
+    PyVar res = py_var(vm, value);
     vm->s_data.push(res);
     vm->s_data.push(res);
     return true;
     return true;
 }
 }
@@ -274,7 +274,7 @@ bool pkpy_is_voidp(pkpy_vm* vm_handle, int i){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         return vm->is_user_type<VoidP>(item);
         return vm->is_user_type<VoidP>(item);
     )
     )
 }
 }
@@ -283,7 +283,7 @@ bool pkpy_to_voidp(pkpy_vm* vm_handle, int i, void** out){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         VoidP& vp = py_cast<VoidP&>(vm, item);
         VoidP& vp = py_cast<VoidP&>(vm, item);
         *out = vp.ptr;
         *out = vp.ptr;
     )
     )
@@ -302,7 +302,7 @@ bool pkpy_is_none(pkpy_vm* vm_handle, int i){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* item = stack_item(vm, i);
+        PyVar item = stack_item(vm, i);
         return item == vm->None;
         return item == vm->None;
     )
     )
 }
 }
@@ -331,9 +331,9 @@ struct TempViewPopper{
 };
 };
 
 
 // function
 // function
-static PyObject* c_function_wrapper(VM* vm, ArgsView args) {
+static PyVar c_function_wrapper(VM* vm, ArgsView args) {
     pkpy_CFunction f = lambda_get_userdata<pkpy_CFunction>(args.begin());
     pkpy_CFunction f = lambda_get_userdata<pkpy_CFunction>(args.begin());
-    PyObject** curr_sp = vm->s_data._sp;
+    PyVar* curr_sp = vm->s_data._sp;
 
 
     vm->__c.s_view.push(args);
     vm->__c.s_view.push(args);
     TempViewPopper _tvp(vm);
     TempViewPopper _tvp(vm);
@@ -342,7 +342,7 @@ static PyObject* c_function_wrapper(VM* vm, ArgsView args) {
 
 
     // propagate_if_errored
     // propagate_if_errored
     if (vm->__c.error != nullptr){
     if (vm->__c.error != nullptr){
-        PyObject* e_obj = PK_OBJ_GET(Exception, vm->__c.error).self();
+        PyVar e_obj = PK_OBJ_GET(Exception, vm->__c.error).self();
         vm->__c.error = nullptr;
         vm->__c.error = nullptr;
         vm->_error(e_obj);
         vm->_error(e_obj);
         return nullptr;
         return nullptr;
@@ -357,7 +357,7 @@ static PyObject* c_function_wrapper(VM* vm, ArgsView args) {
 bool pkpy_push_function(pkpy_vm* vm_handle, const char* sig, pkpy_CFunction f) {
 bool pkpy_push_function(pkpy_vm* vm_handle, const char* sig, pkpy_CFunction f) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* f_obj;
+    PyVar f_obj;
     PK_PROTECTED(
     PK_PROTECTED(
         f_obj = vm->bind(nullptr, sig, c_function_wrapper, f);
         f_obj = vm->bind(nullptr, sig, c_function_wrapper, f);
     )
     )
@@ -370,7 +370,7 @@ bool pkpy_push_module(pkpy_vm* vm_handle, const char* name) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* module = vm->new_module(name);
+        PyVar module = vm->new_module(name);
         vm->s_data.push(module);
         vm->s_data.push(module);
     )
     )
     return true;
     return true;
@@ -381,7 +381,7 @@ bool pkpy_getattr(pkpy_vm* vm_handle, pkpy_CName name) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
-    PyObject* o = vm->s_data.top();
+    PyVar o = vm->s_data.top();
     o = vm->getattr(o, StrName(name), false);
     o = vm->getattr(o, StrName(name), false);
     if(o == nullptr) return false;
     if(o == nullptr) return false;
     vm->s_data.top() = o;
     vm->s_data.top() = o;
@@ -392,8 +392,8 @@ bool pkpy_setattr(pkpy_vm* vm_handle, pkpy_CName name) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(2)
     PK_ASSERT_N_EXTRA_ELEMENTS(2)
-    PyObject* a = vm->s_data.top();
-    PyObject* val = vm->s_data.second();
+    PyVar a = vm->s_data.top();
+    PyVar val = vm->s_data.second();
     PK_PROTECTED(
     PK_PROTECTED(
         vm->setattr(a, StrName(name), val);
         vm->setattr(a, StrName(name), val);
     )
     )
@@ -405,7 +405,7 @@ bool pkpy_setattr(pkpy_vm* vm_handle, pkpy_CName name) {
 bool pkpy_getglobal(pkpy_vm* vm_handle, pkpy_CName name) {
 bool pkpy_getglobal(pkpy_vm* vm_handle, pkpy_CName name) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* o = vm->_main->attr().try_get(StrName(name));
+    PyVar o = vm->_main->attr().try_get(StrName(name));
     if (o == nullptr) {
     if (o == nullptr) {
         o = vm->builtins->attr().try_get(StrName(name));
         o = vm->builtins->attr().try_get(StrName(name));
         if (o == nullptr) return false;
         if (o == nullptr) return false;
@@ -427,7 +427,7 @@ bool pkpy_eval(pkpy_vm* vm_handle, const char* source) {
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_PROTECTED(
     PK_PROTECTED(
         CodeObject_ co = vm->compile(source, "<eval>", EVAL_MODE);
         CodeObject_ co = vm->compile(source, "<eval>", EVAL_MODE);
-        PyObject* ret = vm->_exec(co, vm->_main);
+        PyVar ret = vm->_exec(co, vm->_main);
         vm->s_data.push(ret);
         vm->s_data.push(ret);
     )
     )
     return true;
     return true;
@@ -439,9 +439,9 @@ bool pkpy_unpack_sequence(pkpy_vm* vm_handle, int n) {
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
     auto _lock = vm->heap.gc_scope_lock();
     auto _lock = vm->heap.gc_scope_lock();
     PK_PROTECTED(
     PK_PROTECTED(
-        PyObject* _0 = vm->py_iter(vm->s_data.popx());
+        PyVar _0 = vm->py_iter(vm->s_data.popx());
         for(int i=0; i<n; i++){
         for(int i=0; i<n; i++){
-            PyObject* _1 = vm->py_next(_0);
+            PyVar _1 = vm->py_next(_0);
             if(_1 == vm->StopIteration) vm->ValueError("not enough values to unpack");
             if(_1 == vm->StopIteration) vm->ValueError("not enough values to unpack");
             vm->s_data.push(_1);
             vm->s_data.push(_1);
         }
         }
@@ -454,8 +454,8 @@ bool pkpy_get_unbound_method(pkpy_vm* vm_handle, pkpy_CName name){
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
-    PyObject* o = vm->s_data.top();
-    PyObject* self;
+    PyVar o = vm->s_data.top();
+    PyVar self;
     PK_PROTECTED(
     PK_PROTECTED(
         o = vm->get_unbound_method(o, StrName(name), &self);
         o = vm->get_unbound_method(o, StrName(name), &self);
     )
     )
@@ -469,7 +469,7 @@ bool pkpy_py_repr(pkpy_vm* vm_handle) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
-    PyObject* item = vm->s_data.top();
+    PyVar item = vm->s_data.top();
     PK_PROTECTED(
     PK_PROTECTED(
         item = VAR(vm->py_repr(item));
         item = VAR(vm->py_repr(item));
     )
     )
@@ -481,7 +481,7 @@ bool pkpy_py_str(pkpy_vm* vm_handle) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
     PK_ASSERT_N_EXTRA_ELEMENTS(1)
-    PyObject* item = vm->s_data.top();
+    PyVar item = vm->s_data.top();
     PK_PROTECTED(
     PK_PROTECTED(
         item = VAR(vm->py_str(item));
         item = VAR(vm->py_str(item));
     )
     )
@@ -493,7 +493,7 @@ bool pkpy_py_str(pkpy_vm* vm_handle) {
 bool pkpy_error(pkpy_vm* vm_handle, const char* name, pkpy_CString message) {
 bool pkpy_error(pkpy_vm* vm_handle, const char* name, pkpy_CString message) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
-    PyObject* e_t = vm->_main->attr().try_get_likely_found(name);
+    PyVar e_t = vm->_main->attr().try_get_likely_found(name);
     if(e_t == nullptr){
     if(e_t == nullptr){
         e_t = vm->builtins->attr().try_get_likely_found(name);
         e_t = vm->builtins->attr().try_get_likely_found(name);
         if(e_t == nullptr){
         if(e_t == nullptr){
@@ -533,7 +533,7 @@ bool pkpy_vectorcall(pkpy_vm* vm_handle, int argc) {
     VM* vm = (VM*) vm_handle;
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_NO_ERROR()
     PK_ASSERT_N_EXTRA_ELEMENTS(argc + 2)
     PK_ASSERT_N_EXTRA_ELEMENTS(argc + 2)
-    PyObject* res;
+    PyVar res;
     PK_PROTECTED(
     PK_PROTECTED(
         res = vm->vectorcall(argc);
         res = vm->vectorcall(argc);
     )
     )

+ 4 - 4
src/random.cpp

@@ -133,7 +133,7 @@ struct Random{
         gen.seed((uint32_t)count);
         gen.seed((uint32_t)count);
     }
     }
 
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type){
+    static void _register(VM* vm, PyVar mod, PyVar type){
         vm->bind_func(type, __new__, 1, [](VM* vm, ArgsView args){
         vm->bind_func(type, __new__, 1, [](VM* vm, ArgsView args){
             Type cls = PK_OBJ_GET(Type, args[0]);
             Type cls = PK_OBJ_GET(Type, args[0]);
             return vm->heap.gcnew<Random>(cls);
             return vm->heap.gcnew<Random>(cls);
@@ -187,7 +187,7 @@ struct Random{
         vm->bind(type, "choices(self, population, weights=None, k=1)", [](VM* vm, ArgsView args) {
         vm->bind(type, "choices(self, population, weights=None, k=1)", [](VM* vm, ArgsView args) {
             Random& self = PK_OBJ_GET(Random, args[0]);
             Random& self = PK_OBJ_GET(Random, args[0]);
             ArgsView view = vm->cast_array_view(args[1]);
             ArgsView view = vm->cast_array_view(args[1]);
-            PyObject** data = view.begin();
+            PyVar* data = view.begin();
             int size = view.size();
             int size = view.size();
             if(size == 0) vm->IndexError("cannot choose from an empty sequence");
             if(size == 0) vm->IndexError("cannot choose from an empty sequence");
             pod_vector<f64> cum_weights(size);
             pod_vector<f64> cum_weights(size);
@@ -215,9 +215,9 @@ struct Random{
 };
 };
 
 
 void add_module_random(VM* vm){
 void add_module_random(VM* vm){
-    PyObject* mod = vm->new_module("random");
+    PyVar mod = vm->new_module("random");
     vm->register_user_class<Random>(mod, "Random");
     vm->register_user_class<Random>(mod, "Random");
-    PyObject* instance = vm->new_user_object<Random>();
+    PyVar 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"));

+ 4 - 4
src/tuplelist.cpp

@@ -6,7 +6,7 @@ Tuple::Tuple(int n){
     if(n <= 3){
     if(n <= 3){
         this->_args = _inlined;
         this->_args = _inlined;
     }else{
     }else{
-        this->_args = (PyObject**)pool64_alloc(n * sizeof(void*));
+        this->_args = (PyVar*)pool64_alloc(n * sizeof(void*));
     }
     }
     this->_size = n;
     this->_size = n;
 }
 }
@@ -33,18 +33,18 @@ Tuple::Tuple(List&& other) noexcept {
     other._data = nullptr;
     other._data = nullptr;
 }
 }
 
 
-Tuple::Tuple(PyObject* _0, PyObject* _1): Tuple(2){
+Tuple::Tuple(PyVar _0, PyVar _1): Tuple(2){
     _args[0] = _0;
     _args[0] = _0;
     _args[1] = _1;
     _args[1] = _1;
 }
 }
 
 
-Tuple::Tuple(PyObject* _0, PyObject* _1, PyObject* _2): Tuple(3){
+Tuple::Tuple(PyVar _0, PyVar _1, PyVar _2): Tuple(3){
     _args[0] = _0;
     _args[0] = _0;
     _args[1] = _1;
     _args[1] = _1;
     _args[2] = _2;
     _args[2] = _2;
 }
 }
 
 
-Tuple::Tuple(PyObject* _0, PyObject* _1, PyObject* _2, PyObject* _3): Tuple(4){
+Tuple::Tuple(PyVar _0, PyVar _1, PyVar _2, PyVar _3): Tuple(4){
     _args[0] = _0;
     _args[0] = _0;
     _args[1] = _1;
     _args[1] = _1;
     _args[2] = _2;
     _args[2] = _2;

+ 135 - 135
src/vm.cpp

@@ -10,10 +10,10 @@ namespace pkpy{
 
 
     struct JsonSerializer{
     struct JsonSerializer{
         VM* vm;
         VM* vm;
-        PyObject* root;
+        PyVar root;
         SStream ss;
         SStream ss;
 
 
-        JsonSerializer(VM* vm, PyObject* root) : vm(vm), root(root) {}
+        JsonSerializer(VM* vm, PyVar root) : vm(vm), root(root) {}
 
 
         template<typename T>
         template<typename T>
         void write_array(T& arr){
         void write_array(T& arr){
@@ -28,7 +28,7 @@ namespace pkpy{
         void write_dict(Dict& dict){
         void write_dict(Dict& dict){
             ss << '{';
             ss << '{';
             bool first = true;
             bool first = true;
-            dict.apply([&](PyObject* k, PyObject* v){
+            dict.apply([&](PyVar k, PyVar v){
                 if(!first) ss << ", ";
                 if(!first) ss << ", ";
                 first = false;
                 first = false;
                 if(!is_type(k, VM::tp_str)){
                 if(!is_type(k, VM::tp_str)){
@@ -40,7 +40,7 @@ namespace pkpy{
             ss << '}';
             ss << '}';
         }
         }
 
 
-        void write_object(PyObject* obj){
+        void write_object(PyVar obj){
             Type obj_t = vm->_tp(obj);
             Type obj_t = vm->_tp(obj);
             if(obj == vm->None){
             if(obj == vm->None){
                 ss << "null";
                 ss << "null";
@@ -84,13 +84,13 @@ namespace pkpy{
         __init_builtin_types();
         __init_builtin_types();
     }
     }
 
 
-    Str VM::py_str(PyObject* obj){
+    Str VM::py_str(PyVar obj){
         const PyTypeInfo* ti = _tp_info(obj);
         const PyTypeInfo* ti = _tp_info(obj);
         if(ti->m__str__) return ti->m__str__(this, obj);
         if(ti->m__str__) return ti->m__str__(this, obj);
-        PyObject* self;
-        PyObject* f = get_unbound_method(obj, __str__, &self, false);
+        PyVar self;
+        PyVar f = get_unbound_method(obj, __str__, &self, false);
         if(self != PY_NULL){
         if(self != PY_NULL){
-            PyObject* retval = call_method(self, f);
+            PyVar retval = call_method(self, f);
             if(!is_type(retval, tp_str)){
             if(!is_type(retval, tp_str)){
                 throw std::runtime_error("object.__str__ must return str");
                 throw std::runtime_error("object.__str__ must return str");
             }
             }
@@ -99,32 +99,32 @@ namespace pkpy{
         return py_repr(obj);
         return py_repr(obj);
     }
     }
 
 
-    Str VM::py_repr(PyObject* obj){
+    Str VM::py_repr(PyVar obj){
         const PyTypeInfo* ti = _tp_info(obj);
         const PyTypeInfo* ti = _tp_info(obj);
         if(ti->m__repr__) return ti->m__repr__(this, obj);
         if(ti->m__repr__) return ti->m__repr__(this, obj);
-        PyObject* retval = call_method(obj, __repr__);
+        PyVar retval = call_method(obj, __repr__);
         if(!is_type(retval, tp_str)){
         if(!is_type(retval, tp_str)){
             throw std::runtime_error("object.__repr__ must return str");
             throw std::runtime_error("object.__repr__ must return str");
         }
         }
         return PK_OBJ_GET(Str, retval);
         return PK_OBJ_GET(Str, retval);
     }
     }
 
 
-    Str VM::py_json(PyObject* obj){
+    Str VM::py_json(PyVar obj){
         auto j = JsonSerializer(this, obj);
         auto j = JsonSerializer(this, obj);
         return j.serialize();
         return j.serialize();
     }
     }
 
 
-    PyObject* VM::py_iter(PyObject* obj){
+    PyVar VM::py_iter(PyVar obj){
         const PyTypeInfo* ti = _tp_info(obj);
         const PyTypeInfo* ti = _tp_info(obj);
         if(ti->m__iter__) return ti->m__iter__(this, obj);
         if(ti->m__iter__) return ti->m__iter__(this, obj);
-        PyObject* self;
-        PyObject* iter_f = get_unbound_method(obj, __iter__, &self, false);
+        PyVar self;
+        PyVar iter_f = get_unbound_method(obj, __iter__, &self, false);
         if(self != PY_NULL) return call_method(self, iter_f);
         if(self != PY_NULL) return call_method(self, iter_f);
         TypeError(_type_name(vm, _tp(obj)).escape() + " object is not iterable");
         TypeError(_type_name(vm, _tp(obj)).escape() + " object is not iterable");
         return nullptr;
         return nullptr;
     }
     }
 
 
-    ArgsView VM::cast_array_view(PyObject* obj){
+    ArgsView VM::cast_array_view(PyVar obj){
         if(is_type(obj, VM::tp_list)){
         if(is_type(obj, VM::tp_list)){
             List& list = PK_OBJ_GET(List, obj);
             List& list = PK_OBJ_GET(List, obj);
             return ArgsView(list.begin(), list.end());
             return ArgsView(list.begin(), list.end());
@@ -137,14 +137,14 @@ namespace pkpy{
     }
     }
 
 
     void VM::set_main_argv(int argc, char** argv){
     void VM::set_main_argv(int argc, char** argv){
-        PyObject* mod = vm->_modules["sys"];
+        PyVar mod = vm->_modules["sys"];
         List argv_(argc);
         List argv_(argc);
         for(int i=0; i<argc; i++) argv_[i] = VAR(std::string_view(argv[i]));
         for(int i=0; i<argc; i++) argv_[i] = VAR(std::string_view(argv[i]));
         mod->attr().set("argv", VAR(std::move(argv_)));
         mod->attr().set("argv", VAR(std::move(argv_)));
     }
     }
 
 
-    PyObject* VM::find_name_in_mro(Type cls, StrName name){
-        PyObject* val;
+    PyVar VM::find_name_in_mro(Type cls, StrName name){
+        PyVar val;
         do{
         do{
             val = _t(cls)->attr().try_get(name);
             val = _t(cls)->attr().try_get(name);
             if(val != nullptr) return val;
             if(val != nullptr) return val;
@@ -154,7 +154,7 @@ namespace pkpy{
         return nullptr;
         return nullptr;
     }
     }
 
 
-    bool VM::isinstance(PyObject* obj, Type base){
+    bool VM::isinstance(PyVar obj, Type base){
         return issubclass(_tp(obj), base);
         return issubclass(_tp(obj), base);
     }
     }
 
 
@@ -168,7 +168,7 @@ namespace pkpy{
         return false;
         return false;
     }
     }
 
 
-    PyObject* VM::exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module){
+    PyVar VM::exec(std::string_view source, Str filename, CompileMode mode, PyVar _module){
         if(_module == nullptr) _module = _main;
         if(_module == nullptr) _module = _main;
         try {
         try {
 #if PK_DEBUG_PRECOMPILED_EXEC == 1
 #if PK_DEBUG_PRECOMPILED_EXEC == 1
@@ -197,16 +197,16 @@ namespace pkpy{
         return nullptr;
         return nullptr;
     }
     }
 
 
-    PyObject* VM::exec(std::string_view source){
+    PyVar VM::exec(std::string_view source){
         return exec(source, "main.py", EXEC_MODE);
         return exec(source, "main.py", EXEC_MODE);
     }
     }
 
 
-    PyObject* VM::eval(std::string_view source){
+    PyVar VM::eval(std::string_view source){
         return exec(source, "<eval>", EVAL_MODE);
         return exec(source, "<eval>", EVAL_MODE);
     }
     }
 
 
-    PyObject* VM::new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled){
-        PyObject* obj = heap._new<Type>(tp_type, Type(_all_types.size()));
+    PyVar VM::new_type_object(PyVar mod, StrName name, Type base, bool subclass_enabled){
+        PyVar obj = heap._new<Type>(tp_type, Type(_all_types.size()));
         const PyTypeInfo& base_info = _all_types[base];
         const PyTypeInfo& base_info = _all_types[base];
         if(!base_info.subclass_enabled){
         if(!base_info.subclass_enabled){
             Str error = _S("type ", base_info.name.escape(), " is not `subclass_enabled`");
             Str error = _S("type ", base_info.name.escape(), " is not `subclass_enabled`");
@@ -223,10 +223,10 @@ namespace pkpy{
         return obj;
         return obj;
     }
     }
 
 
-    bool VM::py_eq(PyObject* lhs, PyObject* rhs){
+    bool VM::py_eq(PyVar lhs, PyVar rhs){
         if(lhs == rhs) return true;
         if(lhs == rhs) return true;
         const PyTypeInfo* ti = _tp_info(lhs);
         const PyTypeInfo* ti = _tp_info(lhs);
-        PyObject* res;
+        PyVar res;
         if(ti->m__eq__){
         if(ti->m__eq__){
             res = ti->m__eq__(this, lhs, rhs);
             res = ti->m__eq__(this, lhs, rhs);
             if(res != vm->NotImplemented) return res == vm->True;
             if(res != vm->NotImplemented) return res == vm->True;
@@ -244,8 +244,8 @@ namespace pkpy{
         return false;
         return false;
     }
     }
 
 
-    PyObject* VM::py_op(std::string_view name){
-        PyObject* func;
+    PyVar VM::py_op(std::string_view name){
+        PyVar func;
         auto it = __cached_op_funcs.find(name);
         auto it = __cached_op_funcs.find(name);
         if(it == __cached_op_funcs.end()){
         if(it == __cached_op_funcs.end()){
             func = py_import("operator")->attr(StrName::get(name));
             func = py_import("operator")->attr(StrName::get(name));
@@ -264,7 +264,7 @@ namespace pkpy{
         return index;
         return index;
     }
     }
 
 
-    PyObject* VM::_py_next(const PyTypeInfo* ti, PyObject* obj){
+    PyVar VM::_py_next(const PyTypeInfo* ti, PyVar obj){
         if(ti->m__next__){
         if(ti->m__next__){
             unsigned n = ti->m__next__(this, obj);
             unsigned n = ti->m__next__(this, obj);
             return __pack_next_retval(n);
             return __pack_next_retval(n);
@@ -272,12 +272,12 @@ namespace pkpy{
         return call_method(obj, __next__);
         return call_method(obj, __next__);
     }
     }
 
 
-    PyObject* VM::py_next(PyObject* obj){
+    PyVar VM::py_next(PyVar obj){
         const PyTypeInfo* ti = _tp_info(obj);
         const PyTypeInfo* ti = _tp_info(obj);
         return _py_next(ti, obj);
         return _py_next(ti, obj);
     }
     }
 
 
-    bool VM::py_callable(PyObject* obj){
+    bool VM::py_callable(PyVar obj){
         Type cls = vm->_tp(obj);
         Type cls = vm->_tp(obj);
         switch(cls.index){
         switch(cls.index){
             case VM::tp_function.index: return vm->True;
             case VM::tp_function.index: return vm->True;
@@ -288,13 +288,13 @@ namespace pkpy{
         return vm->find_name_in_mro(cls, __call__) != nullptr;
         return vm->find_name_in_mro(cls, __call__) != nullptr;
     }
     }
 
 
-    PyObject* VM::__minmax_reduce(bool (VM::*op)(PyObject*, PyObject*), PyObject* args, PyObject* key){
+    PyVar VM::__minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key){
         auto _lock = heap.gc_scope_lock();
         auto _lock = heap.gc_scope_lock();
         const Tuple& args_tuple = PK_OBJ_GET(Tuple, args);  // from *args, it must be a tuple
         const Tuple& args_tuple = PK_OBJ_GET(Tuple, args);  // from *args, it must be a tuple
         if(key==vm->None && args_tuple.size()==2){
         if(key==vm->None && args_tuple.size()==2){
             // fast path
             // fast path
-            PyObject* a = args_tuple[0];
-            PyObject* b = args_tuple[1];
+            PyVar a = args_tuple[0];
+            PyVar b = args_tuple[1];
             return (this->*op)(a, b) ? a : b;
             return (this->*op)(a, b) ? a : b;
         }
         }
 
 
@@ -308,7 +308,7 @@ namespace pkpy{
         }
         }
 
 
         if(view.empty()) ValueError("arg is an empty sequence");
         if(view.empty()) ValueError("arg is an empty sequence");
-        PyObject* res = view[0];
+        PyVar res = view[0];
 
 
         if(key == vm->None){
         if(key == vm->None){
             for(int i=1; i<view.size(); i++){
             for(int i=1; i<view.size(); i++){
@@ -317,15 +317,15 @@ namespace pkpy{
         }else{
         }else{
             auto _lock = heap.gc_scope_lock();
             auto _lock = heap.gc_scope_lock();
             for(int i=1; i<view.size(); i++){
             for(int i=1; i<view.size(); i++){
-                PyObject* a = call(key, view[i]);
-                PyObject* b = call(key, res);
+                PyVar a = call(key, view[i]);
+                PyVar b = call(key, res);
                 if((this->*op)(a, b)) res = view[i];
                 if((this->*op)(a, b)) res = view[i];
             }
             }
         }
         }
         return res;
         return res;
     }
     }
 
 
-    PyObject* VM::py_import(Str path, bool throw_err){
+    PyVar VM::py_import(Str path, bool throw_err){
         if(path.empty()) vm->ValueError("empty module name");
         if(path.empty()) vm->ValueError("empty module name");
         static auto f_join = [](const pod_vector<std::string_view>& cpnts){
         static auto f_join = [](const pod_vector<std::string_view>& cpnts){
             SStream ss;
             SStream ss;
@@ -360,7 +360,7 @@ namespace pkpy{
 
 
         // check existing module
         // check existing module
         StrName name(path);
         StrName name(path);
-        PyObject* ext_mod = _modules.try_get(name);
+        PyVar ext_mod = _modules.try_get(name);
         if(ext_mod != nullptr) return ext_mod;
         if(ext_mod != nullptr) return ext_mod;
 
 
         pod_vector<std::string_view> path_cpnts = path.split('.');
         pod_vector<std::string_view> path_cpnts = path.split('.');
@@ -398,7 +398,7 @@ namespace pkpy{
 
 
         Str name_cpnt = path_cpnts.back();
         Str name_cpnt = path_cpnts.back();
         path_cpnts.pop_back();
         path_cpnts.pop_back();
-        PyObject* new_mod = new_module(name_cpnt, f_join(path_cpnts));
+        PyVar new_mod = new_module(name_cpnt, f_join(path_cpnts));
         _exec(code, new_mod);
         _exec(code, new_mod);
         return new_mod;
         return new_mod;
     }
     }
@@ -411,33 +411,33 @@ namespace pkpy{
         _lazy_modules.clear();
         _lazy_modules.clear();
     }
     }
 
 
-PyObject* VM::py_negate(PyObject* obj){
+PyVar VM::py_negate(PyVar obj){
     const PyTypeInfo* ti = _tp_info(obj);
     const PyTypeInfo* ti = _tp_info(obj);
     if(ti->m__neg__) return ti->m__neg__(this, obj);
     if(ti->m__neg__) return ti->m__neg__(this, obj);
     return call_method(obj, __neg__);
     return call_method(obj, __neg__);
 }
 }
 
 
-bool VM::py_bool(PyObject* obj){
+bool VM::py_bool(PyVar obj){
     if(obj == vm->True) return true;
     if(obj == vm->True) return true;
     if(obj == vm->False) return false;
     if(obj == vm->False) return false;
     if(obj == None) return false;
     if(obj == None) return false;
     if(is_int(obj)) return _CAST(i64, obj) != 0;
     if(is_int(obj)) return _CAST(i64, obj) != 0;
     if(is_float(obj)) return _CAST(f64, obj) != 0.0;
     if(is_float(obj)) return _CAST(f64, obj) != 0.0;
-    PyObject* self;
-    PyObject* len_f = get_unbound_method(obj, __len__, &self, false);
+    PyVar self;
+    PyVar len_f = get_unbound_method(obj, __len__, &self, false);
     if(self != PY_NULL){
     if(self != PY_NULL){
-        PyObject* ret = call_method(self, len_f);
+        PyVar ret = call_method(self, len_f);
         return CAST(i64, ret) > 0;
         return CAST(i64, ret) > 0;
     }
     }
     return true;
     return true;
 }
 }
 
 
-List VM::py_list(PyObject* it){
+List VM::py_list(PyVar it){
     auto _lock = heap.gc_scope_lock();
     auto _lock = heap.gc_scope_lock();
     it = py_iter(it);
     it = py_iter(it);
     List list;
     List list;
     const PyTypeInfo* info = _tp_info(it);
     const PyTypeInfo* info = _tp_info(it);
-    PyObject* obj = _py_next(info, it);
+    PyVar obj = _py_next(info, it);
     while(obj != StopIteration){
     while(obj != StopIteration){
         list.push_back(obj);
         list.push_back(obj);
         obj = _py_next(info, it);
         obj = _py_next(info, it);
@@ -489,15 +489,15 @@ void VM::parse_int_slice(const Slice& s, int length, int& start, int& stop, int&
     }
     }
 }
 }
 
 
-i64 VM::py_hash(PyObject* obj){
+i64 VM::py_hash(PyVar obj){
     // https://docs.python.org/3.10/reference/datamodel.html#object.__hash__
     // https://docs.python.org/3.10/reference/datamodel.html#object.__hash__
     const PyTypeInfo* ti = _tp_info(obj);
     const PyTypeInfo* ti = _tp_info(obj);
     if(ti->m__hash__) return ti->m__hash__(this, obj);
     if(ti->m__hash__) return ti->m__hash__(this, obj);
 
 
-    PyObject* self;
-    PyObject* f = get_unbound_method(obj, __hash__, &self, false);
+    PyVar self;
+    PyVar f = get_unbound_method(obj, __hash__, &self, false);
     if(f != nullptr){
     if(f != nullptr){
-        PyObject* ret = call_method(self, f);
+        PyVar ret = call_method(self, f);
         return CAST(i64, ret);
         return CAST(i64, ret);
     }
     }
     // if it is trivial `object`, return PK_BITS
     // if it is trivial `object`, return PK_BITS
@@ -517,7 +517,7 @@ i64 VM::py_hash(PyObject* obj){
     }
     }
 }
 }
 
 
-PyObject* VM::__py_exec_internal(const CodeObject_& code, PyObject* globals, PyObject* locals){
+PyVar VM::__py_exec_internal(const CodeObject_& code, PyVar globals, PyVar locals){
     Frame* frame = &vm->callstack.top();
     Frame* frame = &vm->callstack.top();
 
 
     // fast path
     // fast path
@@ -527,7 +527,7 @@ PyObject* VM::__py_exec_internal(const CodeObject_& code, PyObject* globals, PyO
 
 
     auto _lock = heap.gc_scope_lock();  // for safety
     auto _lock = heap.gc_scope_lock();  // for safety
 
 
-    PyObject* globals_obj = nullptr;
+    PyVar globals_obj = nullptr;
     Dict* globals_dict = nullptr;
     Dict* globals_dict = nullptr;
 
 
     NameDict_ locals_closure = nullptr;
     NameDict_ locals_closure = nullptr;
@@ -544,13 +544,13 @@ PyObject* VM::__py_exec_internal(const CodeObject_& code, PyObject* globals, PyO
             globals_obj = heap.gcnew<DummyInstance>(VM::tp_object);
             globals_obj = heap.gcnew<DummyInstance>(VM::tp_object);
             globals_obj->_enable_instance_dict();
             globals_obj->_enable_instance_dict();
             globals_dict = &PK_OBJ_GET(Dict, globals);
             globals_dict = &PK_OBJ_GET(Dict, globals);
-            globals_dict->apply([&](PyObject* k, PyObject* v){
+            globals_dict->apply([&](PyVar k, PyVar v){
                 globals_obj->attr().set(CAST(Str&, k), v);
                 globals_obj->attr().set(CAST(Str&, k), v);
             });
             });
         }
         }
     }
     }
 
 
-    PyObject* retval = nullptr;
+    PyVar retval = nullptr;
 
 
     if(locals == vm->None){
     if(locals == vm->None){
         retval = vm->_exec(code, globals_obj);   // only globals
         retval = vm->_exec(code, globals_obj);   // only globals
@@ -558,40 +558,40 @@ PyObject* VM::__py_exec_internal(const CodeObject_& code, PyObject* globals, PyO
         check_compatible_type(locals, VM::tp_dict);
         check_compatible_type(locals, VM::tp_dict);
         locals_dict = &PK_OBJ_GET(Dict, locals);
         locals_dict = &PK_OBJ_GET(Dict, locals);
         locals_closure = std::make_shared<NameDict>();
         locals_closure = std::make_shared<NameDict>();
-        locals_dict->apply([&](PyObject* k, PyObject* v){
+        locals_dict->apply([&](PyVar k, PyVar v){
             locals_closure->set(CAST(Str&, k), v);
             locals_closure->set(CAST(Str&, k), v);
         });
         });
-        PyObject* _callable = VAR(Function(__dynamic_func_decl, globals_obj, nullptr, locals_closure));
+        PyVar _callable = VAR(Function(__dynamic_func_decl, globals_obj, nullptr, locals_closure));
         retval = vm->_exec(code.get(), globals_obj, _callable, vm->s_data._sp);
         retval = vm->_exec(code.get(), globals_obj, _callable, vm->s_data._sp);
     }
     }
 
 
     if(globals_dict){
     if(globals_dict){
         globals_dict->clear();
         globals_dict->clear();
-        globals_obj->attr().apply([&](StrName k, PyObject* v){
+        globals_obj->attr().apply([&](StrName k, PyVar v){
             globals_dict->set(VAR(k.sv()), v);
             globals_dict->set(VAR(k.sv()), v);
         });
         });
     }
     }
 
 
     if(locals_dict){
     if(locals_dict){
         locals_dict->clear();
         locals_dict->clear();
-        locals_closure->apply([&](StrName k, PyObject* v){
+        locals_closure->apply([&](StrName k, PyVar v){
             locals_dict->set(VAR(k.sv()), v);
             locals_dict->set(VAR(k.sv()), v);
         });
         });
     }
     }
     return retval;
     return retval;
 }
 }
 
 
-void VM::py_exec(std::string_view source, PyObject* globals, PyObject* locals){
+void VM::py_exec(std::string_view source, PyVar globals, PyVar locals){
     CodeObject_ code = vm->compile(source, "<exec>", EXEC_MODE, true);
     CodeObject_ code = vm->compile(source, "<exec>", EXEC_MODE, true);
     __py_exec_internal(code, globals, locals);
     __py_exec_internal(code, globals, locals);
 }
 }
 
 
-PyObject* VM::py_eval(std::string_view source, PyObject* globals, PyObject* locals){
+PyVar VM::py_eval(std::string_view source, PyVar globals, PyVar locals){
     CodeObject_ code = vm->compile(source, "<eval>", EVAL_MODE, true);
     CodeObject_ code = vm->compile(source, "<eval>", EVAL_MODE, true);
     return __py_exec_internal(code, globals, locals);
     return __py_exec_internal(code, globals, locals);
 }
 }
 
 
-PyObject* VM::__format_object(PyObject* obj, Str spec){
+PyVar VM::__format_object(PyVar obj, Str spec){
     if(spec.empty()) return VAR(py_str(obj));
     if(spec.empty()) return VAR(py_str(obj));
     char type;
     char type;
     switch(spec.end()[-1]){
     switch(spec.end()[-1]){
@@ -676,8 +676,8 @@ PyObject* VM::__format_object(PyObject* obj, Str spec){
     return VAR(ret);
     return VAR(ret);
 }
 }
 
 
-PyObject* VM::new_module(Str name, Str package) {
-    PyObject* obj = heap._new<DummyModule>(tp_module);
+PyVar VM::new_module(Str name, Str package) {
+    PyVar obj = heap._new<DummyModule>(tp_module);
     obj->attr().set(__name__, VAR(name));
     obj->attr().set(__name__, VAR(name));
     obj->attr().set(__package__, VAR(package));
     obj->attr().set(__package__, VAR(package));
     // convert to fullname
     // convert to fullname
@@ -781,7 +781,7 @@ void VM::__log_s_data(const char* title) {
     if(callstack.empty()) return;
     if(callstack.empty()) return;
     SStream ss;
     SStream ss;
     if(title) ss << title << " | ";
     if(title) ss << title << " | ";
-    std::map<PyObject**, int> sp_bases;
+    std::map<PyVar*, int> sp_bases;
     for(Frame& f: callstack.data()){
     for(Frame& f: callstack.data()){
         if(f._sp_base == nullptr) PK_FATAL_ERROR();
         if(f._sp_base == nullptr) PK_FATAL_ERROR();
         sp_bases[f._sp_base] += 1;
         sp_bases[f._sp_base] += 1;
@@ -789,10 +789,10 @@ void VM::__log_s_data(const char* title) {
     Frame* frame = &callstack.top();
     Frame* frame = &callstack.top();
     int line = frame->co->lines[frame->_ip];
     int line = frame->co->lines[frame->_ip];
     ss << frame->co->name << ":" << line << " [";
     ss << frame->co->name << ":" << line << " [";
-    for(PyObject** p=s_data.begin(); p!=s_data.end(); p++){
+    for(PyVar* p=s_data.begin(); p!=s_data.end(); p++){
         ss << std::string(sp_bases[p], '|');
         ss << std::string(sp_bases[p], '|');
         if(sp_bases[p] > 0) ss << " ";
         if(sp_bases[p] > 0) ss << " ";
-        PyObject* obj = *p;
+        PyVar obj = *p;
         if(obj == nullptr) ss << "(nil)";
         if(obj == nullptr) ss << "(nil)";
         else if(obj == PY_NULL) ss << "NULL";
         else if(obj == PY_NULL) ss << "NULL";
         else if(is_int(obj)) ss << CAST(i64, obj);
         else if(is_int(obj)) ss << CAST(i64, obj);
@@ -831,7 +831,7 @@ void VM::__init_builtin_types(){
     _all_types.push_back({heap._new<Type>(Type(1), Type(1)), Type(0), nullptr, "type", false});
     _all_types.push_back({heap._new<Type>(Type(1), Type(1)), Type(0), nullptr, "type", false});
 
 
     auto _new_type = [this](const char* name, Type base=Type(0), bool subclass_enabled=false){
     auto _new_type = [this](const char* name, Type base=Type(0), bool subclass_enabled=false){
-        PyObject* obj = new_type_object(nullptr, name, base, subclass_enabled);
+        PyVar obj = new_type_object(nullptr, name, base, subclass_enabled);
         return PK_OBJ_GET(Type, obj);
         return PK_OBJ_GET(Type, obj);
     };
     };
 
 
@@ -900,14 +900,14 @@ void VM::__init_builtin_types(){
 
 
 // `heap.gc_scope_lock();` needed before calling this function
 // `heap.gc_scope_lock();` needed before calling this function
 void VM::__unpack_as_list(ArgsView args, List& list){
 void VM::__unpack_as_list(ArgsView args, List& list){
-    for(PyObject* obj: args){
+    for(PyVar obj: args){
         if(is_type(obj, tp_star_wrapper)){
         if(is_type(obj, tp_star_wrapper)){
             const StarWrapper& w = _CAST(StarWrapper&, obj);
             const StarWrapper& w = _CAST(StarWrapper&, obj);
             // maybe this check should be done in the compile time
             // maybe this check should be done in the compile time
             if(w.level != 1) TypeError("expected level 1 star wrapper");
             if(w.level != 1) TypeError("expected level 1 star wrapper");
-            PyObject* _0 = py_iter(w.obj);
+            PyVar _0 = py_iter(w.obj);
             const PyTypeInfo* info = _tp_info(_0);
             const PyTypeInfo* info = _tp_info(_0);
-            PyObject* _1 = _py_next(info, _0);
+            PyVar _1 = _py_next(info, _0);
             while(_1 != StopIteration){
             while(_1 != StopIteration){
                 list.push_back(_1);
                 list.push_back(_1);
                 _1 = _py_next(info, _0);
                 _1 = _py_next(info, _0);
@@ -920,7 +920,7 @@ void VM::__unpack_as_list(ArgsView args, List& list){
 
 
 // `heap.gc_scope_lock();` needed before calling this function
 // `heap.gc_scope_lock();` needed before calling this function
 void VM::__unpack_as_dict(ArgsView args, Dict& dict){
 void VM::__unpack_as_dict(ArgsView args, Dict& dict){
-    for(PyObject* obj: args){
+    for(PyVar obj: args){
         if(is_type(obj, tp_star_wrapper)){
         if(is_type(obj, tp_star_wrapper)){
             const StarWrapper& w = _CAST(StarWrapper&, obj);
             const StarWrapper& w = _CAST(StarWrapper&, obj);
             // maybe this check should be done in the compile time
             // maybe this check should be done in the compile time
@@ -936,7 +936,7 @@ void VM::__unpack_as_dict(ArgsView args, Dict& dict){
 }
 }
 
 
 
 
-void VM::__prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, const FuncDecl_& decl){
+void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const FuncDecl_& decl){
     const CodeObject* co = decl->code.get();
     const CodeObject* co = decl->code.get();
     int co_nlocals = co->varnames.size();
     int co_nlocals = co->varnames.size();
     int decl_argc = decl->args.size();
     int decl_argc = decl->args.size();
@@ -969,7 +969,7 @@ void VM::__prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, co
         if(i < args.size()) TypeError(_S("too many arguments", " (", decl->code->name, ')'));
         if(i < args.size()) TypeError(_S("too many arguments", " (", decl->code->name, ')'));
     }
     }
     
     
-    PyObject* vkwargs;
+    PyVar vkwargs;
     if(decl->starred_kwarg != -1){
     if(decl->starred_kwarg != -1){
         vkwargs = VAR(Dict(this));
         vkwargs = VAR(Dict(this));
         buffer[decl->starred_kwarg] = vkwargs;
         buffer[decl->starred_kwarg] = vkwargs;
@@ -995,12 +995,12 @@ void VM::__prepare_py_call(PyObject** buffer, ArgsView args, ArgsView kwargs, co
     }
     }
 }
 }
 
 
-PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
-    PyObject** p1 = s_data._sp - KWARGC*2;
-    PyObject** p0 = p1 - ARGC - 2;
+PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call){
+    PyVar* p1 = s_data._sp - KWARGC*2;
+    PyVar* p0 = p1 - ARGC - 2;
     // [callable, <self>, args..., kwargs...]
     // [callable, <self>, args..., kwargs...]
     //      ^p0                    ^p1      ^_sp
     //      ^p0                    ^p1      ^_sp
-    PyObject* callable = p1[-(ARGC + 2)];
+    PyVar callable = p1[-(ARGC + 2)];
     Type callable_t = _tp(callable);
     Type callable_t = _tp(callable);
 
 
     int method_call = p0[1] != PY_NULL;
     int method_call = p0[1] != PY_NULL;
@@ -1020,8 +1020,8 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
     ArgsView args(p1 - ARGC - method_call, p1);
     ArgsView args(p1 - ARGC - method_call, p1);
     ArgsView kwargs(p1, s_data._sp);
     ArgsView kwargs(p1, s_data._sp);
 
 
-    PyObject** _base = args.begin();
-    PyObject* buffer[PK_MAX_CO_VARNAMES];
+    PyVar* _base = args.begin();
+    PyVar buffer[PK_MAX_CO_VARNAMES];
 
 
     if(callable_t == tp_function){
     if(callable_t == tp_function){
         /*****************_py_call*****************/
         /*****************_py_call*****************/
@@ -1047,7 +1047,7 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
                 //      ^p0                    ^p1      ^_sp
                 //      ^p0                    ^p1      ^_sp
                 s_data.reset(_base + co_nlocals);
                 s_data.reset(_base + co_nlocals);
                 // initialize local variables to PY_NULL
                 // initialize local variables to PY_NULL
-                for(PyObject** p=p1; p!=s_data._sp; p++) *p = PY_NULL;
+                for(PyVar* p=p1; p!=s_data._sp; p++) *p = PY_NULL;
                 break;
                 break;
             case FuncType::EMPTY:
             case FuncType::EMPTY:
                 if(args.size() != fn.decl->args.size()) TypeError(_S(co->name, "() takes ", fn.decl->args.size(), " positional arguments but ", args.size(), " were given"));
                 if(args.size() != fn.decl->args.size()) TypeError(_S(co->name, "() takes ", fn.decl->args.size(), " positional arguments but ", args.size(), " were given"));
@@ -1072,7 +1072,7 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
 
 
     if(callable_t == tp_native_func){
     if(callable_t == tp_native_func){
         const auto& f = PK_OBJ_GET(NativeFunc, callable);
         const auto& f = PK_OBJ_GET(NativeFunc, callable);
-        PyObject* ret;
+        PyVar ret;
         if(f.decl != nullptr){
         if(f.decl != nullptr){
             int co_nlocals = f.decl->code->varnames.size();
             int co_nlocals = f.decl->code->varnames.size();
             __prepare_py_call(buffer, args, kwargs, f.decl);
             __prepare_py_call(buffer, args, kwargs, f.decl);
@@ -1091,8 +1091,8 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
 
 
     if(callable_t == tp_type){
     if(callable_t == tp_type){
         // [type, NULL, args..., kwargs...]
         // [type, NULL, args..., kwargs...]
-        PyObject* new_f = find_name_in_mro(PK_OBJ_GET(Type, callable), __new__);
-        PyObject* obj;
+        PyVar new_f = find_name_in_mro(PK_OBJ_GET(Type, callable), __new__);
+        PyVar obj;
         PK_DEBUG_ASSERT(new_f != nullptr && !method_call);
         PK_DEBUG_ASSERT(new_f != nullptr && !method_call);
         if(new_f == __cached_object_new) {
         if(new_f == __cached_object_new) {
             // fast path for object.__new__
             // fast path for object.__new__
@@ -1101,14 +1101,14 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
             PUSH(new_f);
             PUSH(new_f);
             PUSH(PY_NULL);
             PUSH(PY_NULL);
             PUSH(callable);    // cls
             PUSH(callable);    // cls
-            for(PyObject* o: args) PUSH(o);
-            for(PyObject* o: kwargs) PUSH(o);
+            for(PyVar o: args) PUSH(o);
+            for(PyVar o: kwargs) PUSH(o);
             // if obj is not an instance of `cls`, the behavior is undefined
             // if obj is not an instance of `cls`, the behavior is undefined
             obj = vectorcall(ARGC+1, KWARGC);
             obj = vectorcall(ARGC+1, KWARGC);
         }
         }
 
 
         // __init__
         // __init__
-        PyObject* self;
+        PyVar self;
         callable = get_unbound_method(obj, __init__, &self, false);
         callable = get_unbound_method(obj, __init__, &self, false);
         if (callable != nullptr) {
         if (callable != nullptr) {
             callable_t = _tp(callable);
             callable_t = _tp(callable);
@@ -1127,8 +1127,8 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){
     }
     }
 
 
     // handle `__call__` overload
     // handle `__call__` overload
-    PyObject* self;
-    PyObject* call_f = get_unbound_method(callable, __call__, &self, false);
+    PyVar self;
+    PyVar call_f = get_unbound_method(callable, __call__, &self, false);
     if(self != PY_NULL){
     if(self != PY_NULL){
         p1[-(ARGC + 2)] = call_f;
         p1[-(ARGC + 2)] = call_f;
         p1[-(ARGC + 1)] = self;
         p1[-(ARGC + 1)] = self;
@@ -1147,7 +1147,7 @@ void VM::delattr(PyObject *_0, StrName _name){
 }
 }
 
 
 // https://docs.python.org/3/howto/descriptor.html#invocation-from-an-instance
 // https://docs.python.org/3/howto/descriptor.html#invocation-from-an-instance
-PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err){
+PyVar VM::getattr(PyVar obj, StrName name, bool throw_err){
     Type objtype(0);
     Type objtype(0);
     // handle super() proxy
     // handle super() proxy
     if(is_type(obj, tp_super)){
     if(is_type(obj, tp_super)){
@@ -1157,7 +1157,7 @@ PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err){
     }else{
     }else{
         objtype = _tp(obj);
         objtype = _tp(obj);
     }
     }
-    PyObject* cls_var = find_name_in_mro(objtype, name);
+    PyVar cls_var = find_name_in_mro(objtype, name);
     if(cls_var != nullptr){
     if(cls_var != nullptr){
         // handle descriptor
         // handle descriptor
         if(is_type(cls_var, tp_property)){
         if(is_type(cls_var, tp_property)){
@@ -1167,7 +1167,7 @@ PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err){
     }
     }
     // handle instance __dict__
     // handle instance __dict__
     if(!is_tagged(obj) && obj->is_attr_valid()){
     if(!is_tagged(obj) && obj->is_attr_valid()){
-        PyObject* val;
+        PyVar val;
         if(obj->type == tp_type){
         if(obj->type == tp_type){
             val = find_name_in_mro(PK_OBJ_GET(Type, obj), name);
             val = find_name_in_mro(PK_OBJ_GET(Type, obj), name);
             if(val != nullptr){
             if(val != nullptr){
@@ -1200,7 +1200,7 @@ PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err){
 
 
     const PyTypeInfo* ti = &_all_types[objtype];
     const PyTypeInfo* ti = &_all_types[objtype];
     if(ti->m__getattr__){
     if(ti->m__getattr__){
-        PyObject* ret = ti->m__getattr__(this, obj, name);
+        PyVar ret = ti->m__getattr__(this, obj, name);
         if(ret) return ret;
         if(ret) return ret;
     }
     }
 
 
@@ -1210,7 +1210,7 @@ PyObject* VM::getattr(PyObject* obj, StrName name, bool throw_err){
 
 
 // used by OP_LOAD_METHOD
 // used by OP_LOAD_METHOD
 // try to load a unbound method (fallback to `getattr` if not found)
 // try to load a unbound method (fallback to `getattr` if not found)
-PyObject* VM::get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err, bool fallback){
+PyVar VM::get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_err, bool fallback){
     *self = PY_NULL;
     *self = PY_NULL;
     Type objtype(0);
     Type objtype(0);
     // handle super() proxy
     // handle super() proxy
@@ -1221,7 +1221,7 @@ PyObject* VM::get_unbound_method(PyObject* obj, StrName name, PyObject** self, b
     }else{
     }else{
         objtype = _tp(obj);
         objtype = _tp(obj);
     }
     }
-    PyObject* cls_var = find_name_in_mro(objtype, name);
+    PyVar cls_var = find_name_in_mro(objtype, name);
 
 
     if(fallback){
     if(fallback){
         if(cls_var != nullptr){
         if(cls_var != nullptr){
@@ -1233,7 +1233,7 @@ PyObject* VM::get_unbound_method(PyObject* obj, StrName name, PyObject** self, b
         }
         }
         // handle instance __dict__
         // handle instance __dict__
         if(!is_tagged(obj) && obj->is_attr_valid()){
         if(!is_tagged(obj) && obj->is_attr_valid()){
-            PyObject* val;
+            PyVar val;
             if(obj->type == tp_type){
             if(obj->type == tp_type){
                 val = find_name_in_mro(PK_OBJ_GET(Type, obj), name);
                 val = find_name_in_mro(PK_OBJ_GET(Type, obj), name);
                 if(val != nullptr){
                 if(val != nullptr){
@@ -1271,7 +1271,7 @@ PyObject* VM::get_unbound_method(PyObject* obj, StrName name, PyObject** self, b
 
 
     const PyTypeInfo* ti = &_all_types[objtype];
     const PyTypeInfo* ti = &_all_types[objtype];
     if(fallback && ti->m__getattr__){
     if(fallback && ti->m__getattr__){
-        PyObject* ret = ti->m__getattr__(this, obj, name);
+        PyVar ret = ti->m__getattr__(this, obj, name);
         if(ret) return ret;
         if(ret) return ret;
     }
     }
 
 
@@ -1279,7 +1279,7 @@ PyObject* VM::get_unbound_method(PyObject* obj, StrName name, PyObject** self, b
     return nullptr;
     return nullptr;
 }
 }
 
 
-void VM::setattr(PyObject* obj, StrName name, PyObject* value){
+void VM::setattr(PyVar obj, StrName name, PyVar value){
     Type objtype(0);
     Type objtype(0);
     // handle super() proxy
     // handle super() proxy
     if(is_type(obj, tp_super)){
     if(is_type(obj, tp_super)){
@@ -1289,7 +1289,7 @@ void VM::setattr(PyObject* obj, StrName name, PyObject* value){
     }else{
     }else{
         objtype = _tp(obj);
         objtype = _tp(obj);
     }
     }
-    PyObject* cls_var = find_name_in_mro(objtype, name);
+    PyVar cls_var = find_name_in_mro(objtype, name);
     if(cls_var != nullptr){
     if(cls_var != nullptr){
         // handle descriptor
         // handle descriptor
         if(is_type(cls_var, tp_property)){
         if(is_type(cls_var, tp_property)){
@@ -1314,8 +1314,8 @@ void VM::setattr(PyObject* obj, StrName name, PyObject* value){
     obj->attr().set(name, value);
     obj->attr().set(name, value);
 }
 }
 
 
-PyObject* VM::bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata, BindType bt) {
-    PyObject* nf = VAR(NativeFunc(fn, argc, std::move(userdata)));
+PyVar VM::bind_func(PyVar obj, StrName name, int argc, NativeFuncC fn, any userdata, BindType bt) {
+    PyVar nf = VAR(NativeFunc(fn, argc, std::move(userdata)));
     switch(bt){
     switch(bt){
         case BindType::DEFAULT: break;
         case BindType::DEFAULT: break;
         case BindType::STATICMETHOD: nf = VAR(StaticMethod(nf)); break;
         case BindType::STATICMETHOD: nf = VAR(StaticMethod(nf)); break;
@@ -1325,11 +1325,11 @@ PyObject* VM::bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, a
     return nf;
     return nf;
 }
 }
 
 
-PyObject* VM::bind(PyObject* obj, const char* sig, NativeFuncC fn, any userdata, BindType bt){
+PyVar VM::bind(PyVar obj, const char* sig, NativeFuncC fn, any userdata, BindType bt){
     return bind(obj, sig, nullptr, fn, std::move(userdata), bt);
     return bind(obj, sig, nullptr, fn, std::move(userdata), bt);
 }
 }
 
 
-PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, NativeFuncC fn, any userdata, BindType bt){
+PyVar VM::bind(PyVar obj, const char* sig, const char* docstring, NativeFuncC fn, any userdata, BindType bt){
     CodeObject_ co;
     CodeObject_ co;
     try{
     try{
         // fn(a, b, *c, d=1) -> None
         // fn(a, b, *c, d=1) -> None
@@ -1342,7 +1342,7 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
     }
     }
     FuncDecl_ decl = co->func_decls[0];
     FuncDecl_ decl = co->func_decls[0];
     decl->docstring = docstring;
     decl->docstring = docstring;
-    PyObject* f_obj = VAR(NativeFunc(fn, decl, std::move(userdata)));
+    PyVar f_obj = VAR(NativeFunc(fn, decl, std::move(userdata)));
 
 
     switch(bt){
     switch(bt){
         case BindType::STATICMETHOD:
         case BindType::STATICMETHOD:
@@ -1358,29 +1358,29 @@ PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Native
     return f_obj;
     return f_obj;
 }
 }
 
 
-PyObject* VM::bind_property(PyObject* obj, const char* name, NativeFuncC fget, NativeFuncC fset){
+PyVar VM::bind_property(PyVar obj, const char* name, NativeFuncC fget, NativeFuncC fset){
     PK_ASSERT(is_type(obj, tp_type));
     PK_ASSERT(is_type(obj, tp_type));
     std::string_view name_sv(name); int pos = name_sv.find(':');
     std::string_view name_sv(name); int pos = name_sv.find(':');
     if(pos > 0) name_sv = name_sv.substr(0, pos);
     if(pos > 0) name_sv = name_sv.substr(0, pos);
-    PyObject* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1);
-    PyObject* _1 = vm->None;
+    PyVar _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1);
+    PyVar _1 = vm->None;
     if(fset != nullptr) _1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2);
     if(fset != nullptr) _1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2);
-    PyObject* prop = VAR(Property(_0, _1));
+    PyVar prop = VAR(Property(_0, _1));
     obj->attr().set(StrName(name_sv), prop);
     obj->attr().set(StrName(name_sv), prop);
     return prop;
     return prop;
 }
 }
 
 
 void VM::__builtin_error(StrName type){ _error(call(builtins->attr(type))); }
 void VM::__builtin_error(StrName type){ _error(call(builtins->attr(type))); }
-void VM::__builtin_error(StrName type, PyObject* arg){ _error(call(builtins->attr(type), arg)); }
+void VM::__builtin_error(StrName type, PyVar arg){ _error(call(builtins->attr(type), arg)); }
 void VM::__builtin_error(StrName type, const Str& msg){ __builtin_error(type, VAR(msg)); }
 void VM::__builtin_error(StrName type, const Str& msg){ __builtin_error(type, VAR(msg)); }
 
 
-void VM::BinaryOptError(const char* op, PyObject* _0, PyObject* _1) {
+void VM::BinaryOptError(const char* op, PyVar _0, PyVar _1) {
     StrName name_0 = _type_name(vm, _tp(_0));
     StrName name_0 = _type_name(vm, _tp(_0));
     StrName name_1 = _type_name(vm, _tp(_1));
     StrName name_1 = _type_name(vm, _tp(_1));
     TypeError(_S("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape()));
     TypeError(_S("unsupported operand type(s) for ", op, ": ", name_0.escape(), " and ", name_1.escape()));
 }
 }
 
 
-void VM::AttributeError(PyObject* obj, StrName name){
+void VM::AttributeError(PyVar obj, StrName name){
     if(isinstance(obj, vm->tp_type)){
     if(isinstance(obj, vm->tp_type)){
         __builtin_error("AttributeError", _S("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));
         __builtin_error("AttributeError", _S("type object ", _type_name(vm, PK_OBJ_GET(Type, obj)).escape(), " has no attribute ", name.escape()));
     }else{
     }else{
@@ -1388,7 +1388,7 @@ void VM::AttributeError(PyObject* obj, StrName name){
     }
     }
 }
 }
 
 
-void VM::_error(PyObject* e_obj){
+void VM::_error(PyVar e_obj){
     PK_ASSERT(isinstance(e_obj, tp_exception))
     PK_ASSERT(isinstance(e_obj, tp_exception))
     Exception& e = PK_OBJ_GET(Exception, e_obj);
     Exception& e = PK_OBJ_GET(Exception, e_obj);
     if(callstack.empty()){
     if(callstack.empty()){
@@ -1420,9 +1420,9 @@ void VM::__raise_exc(bool re_raise){
 }
 }
 
 
 void ManagedHeap::mark() {
 void ManagedHeap::mark() {
-    for(PyObject* obj: _no_gc) PK_OBJ_MARK(obj);
+    for(PyVar obj: _no_gc) PK_OBJ_MARK(obj);
     vm->callstack.apply([](Frame& frame){ frame._gc_mark(); });
     vm->callstack.apply([](Frame& frame){ frame._gc_mark(); });
-    for(PyObject* obj: vm->s_data) PK_OBJ_MARK(obj);
+    for(PyVar obj: vm->s_data) PK_OBJ_MARK(obj);
     for(auto [_, co]: vm->__cached_codes) co->_gc_mark();
     for(auto [_, co]: vm->__cached_codes) co->_gc_mark();
     if(vm->__last_exception) PK_OBJ_MARK(vm->__last_exception);
     if(vm->__last_exception) PK_OBJ_MARK(vm->__last_exception);
     if(vm->__curr_class) PK_OBJ_MARK(vm->__curr_class);
     if(vm->__curr_class) PK_OBJ_MARK(vm->__curr_class);
@@ -1435,62 +1435,62 @@ StrName _type_name(VM *vm, Type type){
 }
 }
 
 
 void _gc_mark_namedict(NameDict* t){
 void _gc_mark_namedict(NameDict* t){
-    t->apply([](StrName name, PyObject* obj){
+    t->apply([](StrName name, PyVar obj){
         PK_OBJ_MARK(obj);
         PK_OBJ_MARK(obj);
     });
     });
 }
 }
 
 
-void VM::bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*)){
+void VM::bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar)){
     _all_types[type].m__getitem__ = f;
     _all_types[type].m__getitem__ = f;
     bind_func(type, __getitem__, 2, [](VM* vm, ArgsView args){
     bind_func(type, __getitem__, 2, [](VM* vm, ArgsView args){
-        return lambda_get_userdata<PyObject*(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
+        return lambda_get_userdata<PyVar(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
     }, f);
     }, f);
 }
 }
 
 
-void VM::bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*)){
+void VM::bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar)){
     _all_types[type].m__setitem__ = f;
     _all_types[type].m__setitem__ = f;
     bind_func(type, __setitem__, 3, [](VM* vm, ArgsView args){
     bind_func(type, __setitem__, 3, [](VM* vm, ArgsView args){
-        lambda_get_userdata<void(*)(VM* vm, PyObject*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1], args[2]);
+        lambda_get_userdata<void(*)(VM* vm, PyVar, PyVar, PyVar)>(args.begin())(vm, args[0], args[1], args[2]);
         return vm->None;
         return vm->None;
     }, f);
     }, f);
 }
 }
 
 
-void VM::bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*)){
+void VM::bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar)){
     _all_types[type].m__delitem__ = f;
     _all_types[type].m__delitem__ = f;
     bind_func(type, __delitem__, 2, [](VM* vm, ArgsView args){
     bind_func(type, __delitem__, 2, [](VM* vm, ArgsView args){
-        lambda_get_userdata<void(*)(VM*, PyObject*, PyObject*)>(args.begin())(vm, args[0], args[1]);
+        lambda_get_userdata<void(*)(VM*, PyVar, PyVar)>(args.begin())(vm, args[0], args[1]);
         return vm->None;
         return vm->None;
     }, f);
     }, f);
 }
 }
 
 
-PyObject* VM::__pack_next_retval(unsigned n){
+PyVar VM::__pack_next_retval(unsigned n){
     if(n == 0) return StopIteration;
     if(n == 0) return StopIteration;
     if(n == 1) return s_data.popx();
     if(n == 1) return s_data.popx();
-    PyObject* retval = VAR(s_data.view(n).to_tuple());
+    PyVar retval = VAR(s_data.view(n).to_tuple());
     s_data._sp -= n;
     s_data._sp -= n;
     return retval;
     return retval;
 }
 }
 
 
-void VM::bind__next__(Type type, unsigned (*f)(VM*, PyObject*)){
+void VM::bind__next__(Type type, unsigned (*f)(VM*, PyVar)){
     _all_types[type].m__next__ = f;
     _all_types[type].m__next__ = f;
     bind_func(type, __next__, 1, [](VM* vm, ArgsView args){
     bind_func(type, __next__, 1, [](VM* vm, ArgsView args){
-        int n = lambda_get_userdata<unsigned(*)(VM*, PyObject*)>(args.begin())(vm, args[0]);
+        int n = lambda_get_userdata<unsigned(*)(VM*, PyVar)>(args.begin())(vm, args[0]);
         return vm->__pack_next_retval(n);
         return vm->__pack_next_retval(n);
     }, f);
     }, f);
 }
 }
 
 
-void VM::bind__next__(Type type, PyObject* (*f)(VM*, PyObject*)){
+void VM::bind__next__(Type type, PyVar (*f)(VM*, PyVar)){
     bind_func(type, __next__, 1, [](VM* vm, ArgsView args){
     bind_func(type, __next__, 1, [](VM* vm, ArgsView args){
-        auto f = lambda_get_userdata<PyObject*(*)(VM*, PyObject*)>(args.begin());
+        auto f = lambda_get_userdata<PyVar(*)(VM*, PyVar)>(args.begin());
         return f(vm, args[0]);
         return f(vm, args[0]);
     }, f);
     }, f);
 }
 }
 
 
 #define BIND_UNARY_SPECIAL(name)                                                        \
 #define BIND_UNARY_SPECIAL(name)                                                        \
-    void VM::bind##name(Type type, PyObject* (*f)(VM*, PyObject*)){                     \
+    void VM::bind##name(Type type, PyVar (*f)(VM*, PyVar)){                     \
         _all_types[type].m##name = f;                                                   \
         _all_types[type].m##name = f;                                                   \
         bind_func(type, name, 1, [](VM* vm, ArgsView args){                             \
         bind_func(type, name, 1, [](VM* vm, ArgsView args){                             \
-            return lambda_get_userdata<PyObject*(*)(VM*, PyObject*)>(args.begin())(vm, args[0]);    \
+            return lambda_get_userdata<PyVar(*)(VM*, PyVar)>(args.begin())(vm, args[0]);    \
         }, f);                                                                          \
         }, f);                                                                          \
     }
     }
     BIND_UNARY_SPECIAL(__iter__)
     BIND_UNARY_SPECIAL(__iter__)
@@ -1498,7 +1498,7 @@ void VM::bind__next__(Type type, PyObject* (*f)(VM*, PyObject*)){
     BIND_UNARY_SPECIAL(__invert__)
     BIND_UNARY_SPECIAL(__invert__)
 #undef BIND_UNARY_SPECIAL
 #undef BIND_UNARY_SPECIAL
 
 
-void VM::bind__str__(Type type, Str (*f)(VM*, PyObject*)){
+void VM::bind__str__(Type type, Str (*f)(VM*, PyVar)){
     _all_types[type].m__str__ = f;
     _all_types[type].m__str__ = f;
     bind_func(type, __str__, 1, [](VM* vm, ArgsView args){
     bind_func(type, __str__, 1, [](VM* vm, ArgsView args){
         Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
         Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
@@ -1506,7 +1506,7 @@ void VM::bind__str__(Type type, Str (*f)(VM*, PyObject*)){
     }, f);
     }, f);
 }
 }
 
 
-void VM::bind__repr__(Type type, Str (*f)(VM*, PyObject*)){
+void VM::bind__repr__(Type type, Str (*f)(VM*, PyVar)){
     _all_types[type].m__repr__ = f;
     _all_types[type].m__repr__ = f;
     bind_func(type, __repr__, 1, [](VM* vm, ArgsView args){
     bind_func(type, __repr__, 1, [](VM* vm, ArgsView args){
         Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
         Str s = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
@@ -1514,7 +1514,7 @@ void VM::bind__repr__(Type type, Str (*f)(VM*, PyObject*)){
     }, f);
     }, f);
 }
 }
 
 
-void VM::bind__hash__(Type type, i64 (*f)(VM*, PyObject*)){
+void VM::bind__hash__(Type type, i64 (*f)(VM*, PyVar)){
     _all_types[type].m__hash__ = f;
     _all_types[type].m__hash__ = f;
     bind_func(type, __hash__, 1, [](VM* vm, ArgsView args){
     bind_func(type, __hash__, 1, [](VM* vm, ArgsView args){
         i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
         i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
@@ -1522,7 +1522,7 @@ void VM::bind__hash__(Type type, i64 (*f)(VM*, PyObject*)){
     }, f);
     }, f);
 }
 }
 
 
-void VM::bind__len__(Type type, i64 (*f)(VM*, PyObject*)){
+void VM::bind__len__(Type type, i64 (*f)(VM*, PyVar)){
     _all_types[type].m__len__ = f;
     _all_types[type].m__len__ = f;
     bind_func(type, __len__, 1, [](VM* vm, ArgsView args){
     bind_func(type, __len__, 1, [](VM* vm, ArgsView args){
         i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
         i64 ret = lambda_get_userdata<decltype(f)>(args.begin())(vm, args[0]);
@@ -1703,7 +1703,7 @@ void VM::__breakpoint(){
         if(line == "c" || line == "continue") break;
         if(line == "c" || line == "continue") break;
         if(line == "a" || line == "args"){
         if(line == "a" || line == "args"){
             int i = 0;
             int i = 0;
-            for(PyObject* obj: frame_0->_locals){
+            for(PyVar obj: frame_0->_locals){
                 if(obj == PY_NULL) continue;
                 if(obj == PY_NULL) continue;
                 StrName name = frame_0->co->varnames[i++];
                 StrName name = frame_0->co->varnames[i++];
                 stdout_write(_S(name.sv(), " = ", vm->py_repr(obj), '\n'));
                 stdout_write(_S(name.sv(), " = ", vm->py_repr(obj), '\n'));
@@ -1749,7 +1749,7 @@ void VM::__breakpoint(){
             if(arg.empty()) continue;   // ignore empty command
             if(arg.empty()) continue;   // ignore empty command
             if(cmd == "p" || cmd == "print"){
             if(cmd == "p" || cmd == "print"){
                 CodeObject_ code = compile(arg, "<stdin>", EVAL_MODE, true);
                 CodeObject_ code = compile(arg, "<stdin>", EVAL_MODE, true);
-                PyObject* retval = vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals);
+                PyVar retval = vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals);
                 stdout_write(vm->py_repr(retval));
                 stdout_write(vm->py_repr(retval));
                 stdout_write("\n");
                 stdout_write("\n");
             }else if(cmd == "!"){
             }else if(cmd == "!"){