소스 검색

replace `PyObject*` with `PyVar`

blueloveTH 1 년 전
부모
커밋
7fd4e3fdfb

+ 21 - 21
include/pocketpy/bindings.h

@@ -5,7 +5,7 @@
 
 namespace pkpy{
 struct NativeProxyFuncCBase {
-    virtual PyObject* operator()(VM* vm, ArgsView args) = 0;
+    virtual PyVar operator()(VM* vm, ArgsView args) = 0;
 };
 
 template<typename Ret, typename... Params>
@@ -15,13 +15,13 @@ struct NativeProxyFuncC final: NativeProxyFuncCBase {
     _Fp func;
     NativeProxyFuncC(_Fp func) : func(func) {}
 
-    PyObject* operator()(VM* vm, ArgsView args) override {
+    PyVar operator()(VM* vm, ArgsView args) override {
         PK_DEBUG_ASSERT(args.size() == N);
         return call<Ret>(vm, args, std::make_index_sequence<N>());
     }
 
     template<typename __Ret, size_t... Is>
-    PyObject* call(VM* vm, ArgsView args, std::index_sequence<Is...>){
+    PyVar call(VM* vm, ArgsView args, std::index_sequence<Is...>){
         if constexpr(std::is_void_v<__Ret>){
             func(py_cast<Params>(vm, args[Is])...);
             return vm->None;
@@ -39,13 +39,13 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase {
     _Fp func;
     NativeProxyMethodC(_Fp func) : func(func) {}
 
-    PyObject* operator()(VM* vm, ArgsView args) override {
+    PyVar operator()(VM* vm, ArgsView args) override {
         PK_DEBUG_ASSERT(args.size() == N+1);
         return call<Ret>(vm, args, std::make_index_sequence<N>());
     }
 
     template<typename __Ret, size_t... Is>
-    PyObject* call(VM* vm, ArgsView args, std::index_sequence<Is...>){
+    PyVar call(VM* vm, ArgsView args, std::index_sequence<Is...>){
         T& self = PK_OBJ_GET(T, args[0]);   // use unsafe cast for derived classes
         if constexpr(std::is_void_v<__Ret>){
             (self.*func)(py_cast<Params>(vm, args[Is+1])...);
@@ -57,48 +57,48 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase {
     }
 };
 /*****************************************************************/
-inline PyObject* __proxy_wrapper(VM* vm, ArgsView args){
+inline PyVar __proxy_wrapper(VM* vm, ArgsView args){
     NativeProxyFuncCBase* pf = lambda_get_userdata<NativeProxyFuncCBase*>(args.begin());
     return (*pf)(vm, args);
 }
 
 template<typename Ret, typename... Params>
-PyObject* VM::bind(PyObject* obj, const char* sig, Ret(*func)(Params...), BindType bt){
+PyVar VM::bind(PyVar obj, const char* sig, Ret(*func)(Params...), BindType bt){
     NativeProxyFuncCBase* proxy = new NativeProxyFuncC<Ret, Params...>(func);
     return vm->bind(obj, sig, __proxy_wrapper, proxy, bt);
 }
 
 template<typename Ret, typename T, typename... Params>
-PyObject* VM::bind(PyObject* obj, const char* sig, Ret(T::*func)(Params...), BindType bt){
+PyVar VM::bind(PyVar obj, const char* sig, Ret(T::*func)(Params...), BindType bt){
     NativeProxyFuncCBase* proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
     return vm->bind(obj, sig, __proxy_wrapper, proxy, bt);
 }
 
 template<typename Ret, typename... Params>
-PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Ret(*func)(Params...), BindType bt){
+PyVar VM::bind(PyVar obj, const char* sig, const char* docstring, Ret(*func)(Params...), BindType bt){
     NativeProxyFuncCBase* proxy = new NativeProxyFuncC<Ret, Params...>(func);
     return vm->bind(obj, sig, docstring, __proxy_wrapper, proxy, bt);
 }
 
 template<typename Ret, typename T, typename... Params>
-PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Ret(T::*func)(Params...), BindType bt){
+PyVar VM::bind(PyVar obj, const char* sig, const char* docstring, Ret(T::*func)(Params...), BindType bt){
     NativeProxyFuncCBase* proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
     return vm->bind(obj, sig, docstring, __proxy_wrapper, proxy, bt);
 }
 
 template<typename T, typename F, bool ReadOnly>
-PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){
+PyVar VM::bind_field(PyVar obj, const char* name, F T::*field){
     static_assert(!std::is_reference_v<F>);
     PK_ASSERT(is_type(obj, tp_type));
     std::string_view name_sv(name); int pos = name_sv.find(':');
     if(pos > 0) name_sv = name_sv.substr(0, pos);
-    auto fget = [](VM* vm, ArgsView args) -> PyObject*{
+    auto fget = [](VM* vm, ArgsView args) -> PyVar{
         T& self = PK_OBJ_GET(T, args[0]);
         F T::*field = lambda_get_userdata<F T::*>(args.begin());
         return VAR(self.*field);
     };
-    PyObject* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, field);
-    PyObject* _1 = vm->None;
+    PyVar _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, field);
+    PyVar _1 = vm->None;
     if constexpr (!ReadOnly){
         auto fset = [](VM* vm, ArgsView args){
             T& self = PK_OBJ_GET(T, args[0]);
@@ -108,18 +108,18 @@ PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){
         };
         _1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, field);
     }
-    PyObject* prop = VAR(Property(_0, _1));
+    PyVar prop = VAR(Property(_0, _1));
     obj->attr().set(StrName(name_sv), prop);
     return prop;
 }
 
 template<typename Ret, typename... Params>
-[[deprecated]] void _bind(VM* vm, PyObject* obj, const char* sig, Ret(*func)(Params...)){
+[[deprecated]] void _bind(VM* vm, PyVar obj, const char* sig, Ret(*func)(Params...)){
     return vm->bind(obj, sig, func);
 }
 
 template<typename Ret, typename T, typename... Params>
-[[deprecated]] void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
+[[deprecated]] void _bind(VM* vm, PyVar obj, const char* sig, Ret(T::*func)(Params...)){
     return vm->bind(obj, sig, func);
 }
 /*****************************************************************/
@@ -168,7 +168,7 @@ template<typename Ret, typename T, typename... Params>
         vm->bind_func(type, "fromstruct", 1, [](VM* vm, ArgsView args){             \
             Struct& s = CAST(Struct&, args[0]);                                     \
             if(s.size != sizeof(wT)) vm->ValueError("size mismatch");               \
-            PyObject* obj = vm->new_user_object<wT>();                              \
+            PyVar obj = vm->new_user_object<wT>();                              \
             memcpy(&_CAST(wT&, obj), s.p, sizeof(wT));                              \
             return obj;                                                             \
         }, {}, BindType::STATICMETHOD);                                             \
@@ -187,7 +187,7 @@ template<typename Ret, typename T, typename... Params>
         vm->bind_func(type, "sizeof", 1, [](VM* vm, ArgsView args){               \
             return VAR(sizeof(wT));                                                 \
         });                                                                         \
-        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){  \
             wT& self = _CAST(wT&, _0);                                              \
             if(!vm->isinstance(_1, vm->_tp_user<wT>())) return vm->NotImplemented;  \
             wT& other = _CAST(wT&, _1);                                             \
@@ -195,13 +195,13 @@ template<typename Ret, typename T, typename... Params>
         });                                                                         \
 
 #define PY_POINTER_SETGETITEM(T) \
-        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){  \
             VoidP& self = PK_OBJ_GET(VoidP, _0);                                       \
             i64 i = CAST(i64, _1);                                                      \
             T* tgt = reinterpret_cast<T*>(self.ptr);                                    \
             return VAR(tgt[i]);                                                         \
         });                                                                             \
-        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){  \
             VoidP& self = PK_OBJ_GET(VoidP, _0);                                       \
             i64 i = CAST(i64, _1);                                                      \
             T* tgt = reinterpret_cast<T*>(self.ptr);                                    \

+ 6 - 6
include/pocketpy/cffi.h

@@ -7,7 +7,7 @@ namespace pkpy {
 
 #define PY_CLASS(T, mod, name)                  \
     [[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; }    \
-    [[deprecated]] static PyObject* register_class(VM* vm, PyObject* mod, Type base=Type(0)) {   \
+    [[deprecated]] static PyVar register_class(VM* vm, PyVar mod, Type base=Type(0)) {   \
         return vm->register_user_class<T>(mod, #name, base);                \
     }                                                                       
 
@@ -32,13 +32,13 @@ struct VoidP{
         return ss.str();
     }
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
 #define POINTER_VAR(Tp, NAME)    \
-    inline PyObject* py_var(VM* vm, Tp val){    \
+    inline PyVar py_var(VM* vm, Tp val){    \
         const static std::pair<StrName, StrName> P("c", NAME);      \
-        PyObject* type = vm->_modules[P.first]->attr(P.second);     \
+        PyVar type = vm->_modules[P.first]->attr(P.second);     \
         return vm->heap.gcnew<VoidP>(PK_OBJ_GET(Type, type), val);  \
     }
 
@@ -84,7 +84,7 @@ struct Struct{
     Struct(const Struct& other): Struct(other.p, other.size){}
     ~Struct(){ if(p!=_inlined) free(p); }
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
 static_assert(sizeof(Py_<Struct>) <= 64);
@@ -92,7 +92,7 @@ static_assert(sizeof(Py_<Tuple>) <= 64);
 
 /***********************************************/
 template<typename Tp>
-Tp to_void_p(VM* vm, PyObject* var){
+Tp to_void_p(VM* vm, PyVar var){
     static_assert(std::is_pointer_v<Tp>);
     if(var == vm->None) return nullptr;     // None can be casted to any pointer implicitly
     VoidP& p = CAST(VoidP&, var);

+ 8 - 8
include/pocketpy/codeobject.h

@@ -65,7 +65,7 @@ struct CodeObject {
     std::vector<int> iblocks;       // block index for each bytecode
     std::vector<LineInfo> lines;
     
-    small_vector_2<PyObject*, 8> consts;         // constants
+    small_vector_2<PyVar, 8> consts;         // constants
     small_vector_2<StrName, 8> varnames;         // local variables
 
     NameDictInt varnames_inv;
@@ -96,7 +96,7 @@ struct FuncDecl {
     struct KwArg {
         int index;              // index in co->varnames
         StrName key;            // name of this argument
-        PyObject* value;        // default value
+        PyVar value;        // default value
     };
     CodeObject_ code;           // code object of this function
 
@@ -113,7 +113,7 @@ struct FuncDecl {
 
     NameDictInt kw_to_index;
 
-    void add_kwarg(int index, StrName key, PyObject* value){
+    void add_kwarg(int index, StrName key, PyVar value){
         kw_to_index.set(key, index);
         kwargs.push_back(KwArg{index, key, value});
     }
@@ -131,16 +131,16 @@ struct NativeFunc {
     NativeFunc(NativeFuncC f, FuncDecl_ decl, any userdata={}): f(f), argc(-1), decl(decl), _userdata(std::move(userdata)) {}
 
     void check_size(VM* vm, ArgsView args) const;
-    PyObject* call(VM* vm, ArgsView args) const { return f(vm, args); }
+    PyVar call(VM* vm, ArgsView args) const { return f(vm, args); }
 };
 
 struct Function{
     FuncDecl_ decl;
-    PyObject* _module;  // weak ref
-    PyObject* _class;   // weak ref
+    PyVar _module;  // weak ref
+    PyVar _class;   // weak ref
     NameDict_ _closure;
 
-    explicit Function(FuncDecl_ decl, PyObject* _module, PyObject* _class, NameDict_ _closure):
+    explicit Function(FuncDecl_ decl, PyVar _module, PyVar _class, NameDict_ _closure):
         decl(decl), _module(_module), _class(_class), _closure(_closure) {}
 };
 
@@ -172,7 +172,7 @@ struct Py_<NativeFunc> final: PyObject {
 };
 
 template<typename T>
-T& lambda_get_userdata(PyObject** p){
+T& lambda_get_userdata(PyVar* p){
     static_assert(std::is_same_v<T, std::decay_t<T>>);
     int offset = p[-1] != PY_NULL ? -1 : -2;
     return PK_OBJ_GET(NativeFunc, p[offset])._userdata.cast<T>();

+ 2 - 2
include/pocketpy/compiler.h

@@ -112,8 +112,8 @@ class Compiler {
     void _compile_f_args(FuncDecl_ decl, bool enable_type_hints);
     void compile_function(const Expr_vector& decorators={});
 
-    PyObject* to_object(const TokenValue& value);
-    PyObject* read_literal();
+    PyVar to_object(const TokenValue& value);
+    PyVar read_literal();
 
     void SyntaxError(Str msg){ lexer.throw_err("SyntaxError", msg, err().line, err().start); }
     void SyntaxError(){ lexer.throw_err("SyntaxError", "invalid syntax", err().line, err().start); }

+ 8 - 8
include/pocketpy/dict.h

@@ -9,8 +9,8 @@ namespace pkpy{
 
 struct Dict{
     struct Item{
-        PyObject* first;
-        PyObject* second;
+        PyVar first;
+        PyVar second;
     };
 
     struct ItemNode{
@@ -41,16 +41,16 @@ struct Dict{
 
     int size() const { return _size; }
 
-    void _probe_0(PyObject* key, bool& ok, int& i) const;
-    void _probe_1(PyObject* key, bool& ok, int& i) const;
+    void _probe_0(PyVar key, bool& ok, int& i) const;
+    void _probe_1(PyVar key, bool& ok, int& i) const;
 
-    void set(PyObject* key, PyObject* val);
+    void set(PyVar key, PyVar val);
     void _rehash();
 
-    PyObject* try_get(PyObject* key) const;
+    PyVar try_get(PyVar key) const;
 
-    bool contains(PyObject* key) const;
-    bool erase(PyObject* key);
+    bool contains(PyVar key) const;
+    bool erase(PyVar key);
     void update(const Dict& other);
 
     template<typename __Func>

+ 2 - 2
include/pocketpy/error.h

@@ -62,12 +62,12 @@ struct Exception {
     int _ip_on_error;
     void* _code_on_error;
 
-    PyObject* _self;    // weak reference
+    PyVar _self;    // weak reference
     
     stack<ExceptionLine> stacktrace;
     Exception(StrName type): type(type), is_re(true), _ip_on_error(-1), _code_on_error(nullptr), _self(nullptr) {}
 
-    PyObject* self() const{
+    PyVar self() const{
         PK_ASSERT(_self != nullptr);
         return _self;
     }

+ 1 - 1
include/pocketpy/expr.h

@@ -110,7 +110,7 @@ struct CodeEmitContext{
     void patch_jump(int index);
     bool add_label(StrName name);
     int add_varname(StrName name);
-    int add_const(PyObject*);
+    int add_const(PyVar);
     int add_const_string(std::string_view);
     int add_func_decl(FuncDecl_ decl);
     void emit_store_name(NameScope scope, StrName name, int line);

+ 33 - 33
include/pocketpy/frame.h

@@ -12,55 +12,55 @@ namespace pkpy{
 struct FastLocals{
     // this is a weak reference
     const CodeObject* co;
-    PyObject** a;
+    PyVar* a;
 
     int size() const{ return co->varnames.size();}
 
-    PyObject*& operator[](int i){ return a[i]; }
-    PyObject* operator[](int i) const { return a[i]; }
+    PyVar& operator[](int i){ return a[i]; }
+    PyVar operator[](int i) const { return a[i]; }
 
-    FastLocals(const CodeObject* co, PyObject** a): co(co), a(a) {}
+    FastLocals(const CodeObject* co, PyVar* a): co(co), a(a) {}
 
-    PyObject** try_get_name(StrName name);
+    PyVar* try_get_name(StrName name);
     NameDict_ to_namedict();
 
-    PyObject** begin() const { return a; }
-    PyObject** end() const { return a + size(); }
+    PyVar* begin() const { return a; }
+    PyVar* end() const { return a + size(); }
 };
 
 struct ValueStack {
     // We allocate extra PK_VM_STACK_SIZE/128 places to keep `_sp` valid when `is_overflow() == true`.
-    PyObject* _begin[PK_VM_STACK_SIZE + PK_VM_STACK_SIZE/128];
-    PyObject** _sp;
-    PyObject** _max_end;
+    PyVar _begin[PK_VM_STACK_SIZE + PK_VM_STACK_SIZE/128];
+    PyVar* _sp;
+    PyVar* _max_end;
 
     static constexpr size_t max_size() { return PK_VM_STACK_SIZE; }
 
     ValueStack(): _sp(_begin), _max_end(_begin + PK_VM_STACK_SIZE) {}
 
-    PyObject*& top(){ return _sp[-1]; }
-    PyObject* top() const { return _sp[-1]; }
-    PyObject*& second(){ return _sp[-2]; }
-    PyObject* second() const { return _sp[-2]; }
-    PyObject*& third(){ return _sp[-3]; }
-    PyObject* third() const { return _sp[-3]; }
-    PyObject*& peek(int n){ return _sp[-n]; }
-    PyObject* peek(int n) const { return _sp[-n]; }
-    void push(PyObject* v){ *_sp++ = v; }
+    PyVar& top(){ return _sp[-1]; }
+    PyVar top() const { return _sp[-1]; }
+    PyVar& second(){ return _sp[-2]; }
+    PyVar second() const { return _sp[-2]; }
+    PyVar& third(){ return _sp[-3]; }
+    PyVar third() const { return _sp[-3]; }
+    PyVar& peek(int n){ return _sp[-n]; }
+    PyVar peek(int n) const { return _sp[-n]; }
+    void push(PyVar v){ *_sp++ = v; }
     void pop(){ --_sp; }
-    PyObject* popx(){ return *--_sp; }
+    PyVar popx(){ return *--_sp; }
     ArgsView view(int n){ return ArgsView(_sp-n, _sp); }
     void shrink(int n){ _sp -= n; }
     int size() const { return _sp - _begin; }
     bool empty() const { return _sp == _begin; }
-    PyObject** begin() { return _begin; }
-    PyObject** end() { return _sp; }
-    void reset(PyObject** sp) { _sp = sp; }
+    PyVar* begin() { return _begin; }
+    PyVar* end() { return _sp; }
+    void reset(PyVar* sp) { _sp = sp; }
     void clear() { _sp = _begin; }
     bool is_overflow() const { return _sp >= _max_end; }
 
-    PyObject* operator[](int i) const { return _begin[i]; }
-    PyObject*& operator[](int i) { return _begin[i]; }
+    PyVar operator[](int i) const { return _begin[i]; }
+    PyVar& operator[](int i) { return _begin[i]; }
     
     ValueStack(const ValueStack&) = delete;
     ValueStack(ValueStack&&) = delete;
@@ -72,26 +72,26 @@ struct Frame {
     int _ip;
     int _next_ip;
     // This is for unwinding only, use `actual_sp_base()` for value stack access
-    PyObject** _sp_base;
+    PyVar* _sp_base;
 
     const CodeObject* co;
-    PyObject* _module;
-    PyObject* _callable;    // a function object or nullptr (global scope)
+    PyVar _module;
+    PyVar _callable;    // a function object or nullptr (global scope)
     FastLocals _locals;
 
     NameDict& f_globals() { return _module->attr(); }
-    PyObject* f_closure_try_get(StrName name);
+    PyVar f_closure_try_get(StrName name);
 
     // function scope
-    Frame(PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable, PyObject** _locals_base)
+    Frame(PyVar* p0, const CodeObject* co, PyVar _module, PyVar _callable, PyVar* _locals_base)
             : _ip(-1), _next_ip(0), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(co, _locals_base) { }
 
     // exec/eval
-    Frame(PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable, FastLocals _locals)
+    Frame(PyVar* p0, const CodeObject* co, PyVar _module, PyVar _callable, FastLocals _locals)
             : _ip(-1), _next_ip(0), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(_locals) { }
 
     // global scope
-    Frame(PyObject** p0, const CodeObject_& co, PyObject* _module)
+    Frame(PyVar* p0, const CodeObject_& co, PyVar _module)
             : _ip(-1), _next_ip(0), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _locals(co.get(), p0) {}
 
     int next_bytecode() {
@@ -100,7 +100,7 @@ struct Frame {
         return _ip;
     }
 
-    PyObject** actual_sp_base() const { return _locals.a; }
+    PyVar* actual_sp_base() const { return _locals.a; }
 
     int stack_size(ValueStack* _s) const { return _s->_sp - actual_sp_base(); }
     ArgsView stack_view(ValueStack* _s) const { return ArgsView(actual_sp_base(), _s->_sp); }

+ 7 - 7
include/pocketpy/gc.h

@@ -8,10 +8,10 @@
 
 namespace pkpy {
 struct ManagedHeap{
-    std::vector<PyObject*> _no_gc;
-    std::vector<PyObject*> gen;
+    std::vector<PyVar> _no_gc;
+    std::vector<PyVar> gen;
     VM* vm;
-    void (*_gc_on_delete)(VM*, PyObject*) = nullptr;
+    void (*_gc_on_delete)(VM*, PyVar) = nullptr;
     void (*_gc_marker_ex)(VM*) = nullptr;
 
     ManagedHeap(VM* vm): vm(vm) {}
@@ -39,20 +39,20 @@ struct ManagedHeap{
     /********************/
 
     template<typename T, typename... Args>
-    PyObject* gcnew(Type type, Args&&... args){
+    PyVar gcnew(Type type, Args&&... args){
         using __T = Py_<std::decay_t<T>>;
         // https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
-        PyObject* obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
+        PyVar obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
         gen.push_back(obj);
         gc_counter++;
         return obj;
     }
 
     template<typename T, typename... Args>
-    PyObject* _new(Type type, Args&&... args){
+    PyVar _new(Type type, Args&&... args){
         using __T = Py_<std::decay_t<T>>;
         // https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
-        PyObject* obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
+        PyVar obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
         obj->gc_enabled = false;
         _no_gc.push_back(obj);
         return obj;

+ 17 - 17
include/pocketpy/iter.h

@@ -11,28 +11,28 @@ struct RangeIter{
     i64 current;
     RangeIter(Range r) : r(r), current(r.start) {}
 
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
 struct ArrayIter{
-    PyObject* ref;
-    PyObject** begin;
-    PyObject** end;
-    PyObject** current;
+    PyVar ref;
+    PyVar* begin;
+    PyVar* end;
+    PyVar* current;
 
-    ArrayIter(PyObject* ref, PyObject** begin, PyObject** end)
+    ArrayIter(PyVar ref, PyVar* begin, PyVar* end)
         : ref(ref), begin(begin), end(end), current(begin) {}
 
     void _gc_mark() const{ PK_OBJ_MARK(ref); }
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
 struct StringIter{
-    PyObject* ref;
+    PyVar ref;
     int i;      // byte index
-    StringIter(PyObject* ref) : ref(ref), i(0) {}
+    StringIter(PyVar ref) : ref(ref), i(0) {}
     void _gc_mark() const{ PK_OBJ_MARK(ref); }
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
 struct Generator{
@@ -41,26 +41,26 @@ struct Generator{
     List s_backup;
 
     Generator(Frame&& frame, ArgsView buffer): frame(std::move(frame)), state(0) {
-        for(PyObject* obj: buffer) s_backup.push_back(obj);
+        for(PyVar obj: buffer) s_backup.push_back(obj);
     }
 
     void _gc_mark() const{
         frame._gc_mark();
-        for(PyObject* obj: s_backup) PK_OBJ_MARK(obj);
+        for(PyVar obj: s_backup) PK_OBJ_MARK(obj);
     }
 
-    PyObject* next(VM* vm);
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    PyVar next(VM* vm);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
 struct DictItemsIter{
-    PyObject* ref;
+    PyVar ref;
     int i;
-    DictItemsIter(PyObject* ref) : ref(ref) {
+    DictItemsIter(PyVar ref) : ref(ref) {
         i = PK_OBJ_GET(Dict, ref)._head_idx;
     }
     void _gc_mark() const{ PK_OBJ_MARK(ref); }
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 };
 
 } // namespace pkpy

+ 4 - 4
include/pocketpy/linalg.h

@@ -7,7 +7,7 @@ namespace pkpy{
 inline bool isclose(float a, float b){ return std::fabs(a - b) < 1e-4; }
 
 struct Vec2{
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 
     float x, y;
     Vec2() : x(0.0f), y(0.0f) {}
@@ -32,7 +32,7 @@ struct Vec2{
 };
 
 struct Vec3{
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 
     float x, y, z;
     Vec3() : x(0.0f), y(0.0f), z(0.0f) {}
@@ -56,7 +56,7 @@ struct Vec3{
 };
 
 struct Vec4{
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 
     float x, y, z, w;
     Vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
@@ -79,7 +79,7 @@ struct Vec4{
 };
 
 struct Mat3x3{
-    static void _register(VM* vm, PyObject* mod, PyObject* type);
+    static void _register(VM* vm, PyVar mod, PyVar type);
 
     union {
         struct {

+ 1 - 1
include/pocketpy/namedict.h

@@ -334,7 +334,7 @@ struct NameDictImpl{
     }
 };
 
-using NameDict = NameDictImpl<PyObject*>;
+using NameDict = NameDictImpl<PyVar>;
 using NameDict_ = std::shared_ptr<NameDict>;
 using NameDictInt = NameDictImpl<int>;
 

+ 36 - 36
include/pocketpy/obj.h

@@ -10,9 +10,9 @@ struct Frame;
 class VM;
 
 #if PK_ENABLE_STD_FUNCTION
-using NativeFuncC = std::function<PyObject*(VM*, ArgsView)>;
+using NativeFuncC = std::function<PyVar(VM*, ArgsView)>;
 #else
-typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
+typedef PyVar (*NativeFuncC)(VM*, ArgsView);
 #endif
 
 enum class BindType{
@@ -22,25 +22,25 @@ enum class BindType{
 };
 
 struct BoundMethod {
-    PyObject* self;
-    PyObject* func;
-    BoundMethod(PyObject* self, PyObject* func) : self(self), func(func) {}
+    PyVar self;
+    PyVar func;
+    BoundMethod(PyVar self, PyVar func) : self(self), func(func) {}
 };
 
 struct StaticMethod{
-    PyObject* func;
-    StaticMethod(PyObject* func) : func(func) {}
+    PyVar func;
+    StaticMethod(PyVar func) : func(func) {}
 };
 
 struct ClassMethod{
-    PyObject* func;
-    ClassMethod(PyObject* func) : func(func) {}
+    PyVar func;
+    ClassMethod(PyVar func) : func(func) {}
 };
 
 struct Property{
-    PyObject* getter;
-    PyObject* setter;
-    Property(PyObject* getter, PyObject* setter) : getter(getter), setter(setter) {}
+    PyVar getter;
+    PyVar setter;
+    Property(PyVar getter, PyVar setter) : getter(getter), setter(setter) {}
 };
 
 struct Range {
@@ -51,8 +51,8 @@ struct Range {
 
 struct StarWrapper{
     int level;      // either 1 or 2
-    PyObject* obj;
-    StarWrapper(int level, PyObject* obj) : level(level), obj(obj) {}
+    PyVar obj;
+    StarWrapper(int level, PyVar obj) : level(level), obj(obj) {}
 };
 
 struct Bytes{
@@ -84,13 +84,13 @@ struct Bytes{
     ~Bytes(){ delete[] _data;}
 };
 
-using Super = std::pair<PyObject*, Type>;
+using Super = std::pair<PyVar, Type>;
 
 struct Slice {
-    PyObject* start;
-    PyObject* stop;
-    PyObject* step;
-    Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {}
+    PyVar start;
+    PyVar stop;
+    PyVar step;
+    Slice(PyVar start, PyVar stop, PyVar step) : start(start), stop(stop), step(step) {}
 };
 
 struct PyObject{
@@ -106,7 +106,7 @@ struct PyObject{
         return *_attr;
     }
 
-    PyObject* attr(StrName name) const {
+    PyVar attr(StrName name) const {
         PK_DEBUG_ASSERT(is_attr_valid())
         return (*_attr)[name];
     }
@@ -128,13 +128,13 @@ struct PyObject{
 const int kTpIntIndex = 2;
 const int kTpFloatIndex = 3;
 
-inline bool is_tagged(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) != 0b00; }
-inline bool is_small_int(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) == 0b10; }
-inline bool is_heap_int(PyObject* p) noexcept { return !is_tagged(p) && p->type.index == kTpIntIndex; }
-inline bool is_float(PyObject* p) noexcept { return !is_tagged(p) && p->type.index == kTpFloatIndex; }
-inline bool is_int(PyObject* p) noexcept { return is_small_int(p) || is_heap_int(p); }
+inline bool is_tagged(PyVar p) noexcept { return (PK_BITS(p) & 0b11) != 0b00; }
+inline bool is_small_int(PyVar p) noexcept { return (PK_BITS(p) & 0b11) == 0b10; }
+inline bool is_heap_int(PyVar p) noexcept { return !is_tagged(p) && p->type.index == kTpIntIndex; }
+inline bool is_float(PyVar p) noexcept { return !is_tagged(p) && p->type.index == kTpFloatIndex; }
+inline bool is_int(PyVar p) noexcept { return is_small_int(p) || is_heap_int(p); }
 
-inline bool is_type(PyObject* obj, Type type) {
+inline bool is_type(PyVar obj, Type type) {
     PK_DEBUG_ASSERT(obj != nullptr)
     return is_small_int(obj) ? type.index == kTpIntIndex : obj->type == type;
 }
@@ -158,15 +158,15 @@ struct Py_ final: PyObject {
 };
 
 struct MappingProxy{
-    PyObject* obj;
-    MappingProxy(PyObject* obj) : obj(obj) {}
+    PyVar obj;
+    MappingProxy(PyVar obj) : obj(obj) {}
     NameDict& attr() { return obj->attr(); }
 };
 
 void _gc_mark_namedict(NameDict*);
 StrName _type_name(VM* vm, Type type);
-template<typename T> T to_void_p(VM*, PyObject*);
-PyObject* from_void_p(VM*, void*);
+template<typename T> T to_void_p(VM*, PyVar);
+PyVar from_void_p(VM*, void*);
 
 
 #define PK_OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
@@ -193,7 +193,7 @@ struct Py_<i64> final: PyObject {
     void _obj_gc_mark() override {}
 };
 
-inline bool try_cast_int(PyObject* obj, i64* val) noexcept {
+inline bool try_cast_int(PyVar obj, i64* val) noexcept {
     if(is_small_int(obj)){
         *val = PK_BITS(obj) >> 2;
         return true;
@@ -212,7 +212,7 @@ struct Py_<List> final: PyObject {
     Py_(Type type, const List& val): PyObject(type), _value(val) {}
 
     void _obj_gc_mark() override {
-        for(PyObject* obj: _value) PK_OBJ_MARK(obj);
+        for(PyVar obj: _value) PK_OBJ_MARK(obj);
     }
 };
 
@@ -223,7 +223,7 @@ struct Py_<Tuple> final: PyObject {
     Py_(Type type, const Tuple& val): PyObject(type), _value(val) {}
 
     void _obj_gc_mark() override {
-        for(PyObject* obj: _value) PK_OBJ_MARK(obj);
+        for(PyVar obj: _value) PK_OBJ_MARK(obj);
     }
 };
 
@@ -329,8 +329,8 @@ struct Py_<DummyModule> final: PyObject {
     void _obj_gc_mark() override {}
 };
 
-extern PyObject* const PY_NULL;
-extern PyObject* const PY_OP_CALL;
-extern PyObject* const PY_OP_YIELD;
+extern PyVar const PY_NULL;
+extern PyVar const PY_OP_CALL;
+extern PyVar const PY_OP_YIELD;
 
 }   // namespace pkpy

+ 17 - 17
include/pocketpy/tuplelist.h

@@ -7,11 +7,11 @@
 
 namespace pkpy {
 
-using List = pod_vector<PyObject*, 4>;
+using List = pod_vector<PyVar, 4>;
 
 struct Tuple {
-    PyObject** _args;
-    PyObject* _inlined[3];
+    PyVar* _args;
+    PyVar _inlined[3];
     int _size;
 
     Tuple(int n);
@@ -20,34 +20,34 @@ struct Tuple {
     Tuple(List&& other) noexcept;
     ~Tuple();
 
-    Tuple(PyObject*, PyObject*);
-    Tuple(PyObject*, PyObject*, PyObject*);
-    Tuple(PyObject*, PyObject*, PyObject*, PyObject*);
+    Tuple(PyVar, PyVar);
+    Tuple(PyVar, PyVar, PyVar);
+    Tuple(PyVar, PyVar, PyVar, PyVar);
 
     bool is_inlined() const { return _args == _inlined; }
-    PyObject*& operator[](int i){ return _args[i]; }
-    PyObject* operator[](int i) const { return _args[i]; }
+    PyVar& operator[](int i){ return _args[i]; }
+    PyVar operator[](int i) const { return _args[i]; }
 
     int size() const { return _size; }
 
-    PyObject** begin() const { return _args; }
-    PyObject** end() const { return _args + _size; }
-    PyObject** data() const { return _args; }
+    PyVar* begin() const { return _args; }
+    PyVar* end() const { return _args + _size; }
+    PyVar* data() const { return _args; }
 };
 
 // a lightweight view for function args, it does not own the memory
 struct ArgsView{
-    PyObject** _begin;
-    PyObject** _end;
+    PyVar* _begin;
+    PyVar* _end;
 
-    ArgsView(PyObject** begin, PyObject** end) : _begin(begin), _end(end) {}
+    ArgsView(PyVar* begin, PyVar* end) : _begin(begin), _end(end) {}
     ArgsView(const Tuple& t) : _begin(t.begin()), _end(t.end()) {}
 
-    PyObject** begin() const { return _begin; }
-    PyObject** end() const { return _end; }
+    PyVar* begin() const { return _begin; }
+    PyVar* end() const { return _end; }
     int size() const { return _end - _begin; }
     bool empty() const { return _begin == _end; }
-    PyObject* operator[](int i) const { return _begin[i]; }
+    PyVar operator[](int i) const { return _begin[i]; }
 
     List to_list() const;
     Tuple to_tuple() const;

+ 126 - 126
include/pocketpy/vm.h

@@ -26,8 +26,8 @@ namespace pkpy{
 #define POPX()            (s_data.popx())
 #define STACK_VIEW(n)     (s_data.view(n))
 
-typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
-typedef void (*RegisterFunc)(VM*, PyObject*, PyObject*);
+typedef PyVar (*BinaryFuncC)(VM*, PyVar, PyVar);
+typedef void (*RegisterFunc)(VM*, PyVar, PyVar);
 
 #if PK_ENABLE_PROFILER
 struct NextBreakpoint{
@@ -42,23 +42,23 @@ struct NextBreakpoint{
 #endif
 
 struct PyTypeInfo{
-    PyObject* obj;      // never be garbage collected
+    PyVar obj;      // never be garbage collected
     Type base;
-    PyObject* mod;      // never be garbage collected
+    PyVar mod;      // never be garbage collected
     StrName name;
     bool subclass_enabled;
 
     std::vector<StrName> annotated_fields = {};
 
     // unary operators
-    Str (*m__repr__)(VM* vm, PyObject*) = nullptr;
-    Str (*m__str__)(VM* vm, PyObject*) = nullptr;
-    i64 (*m__hash__)(VM* vm, PyObject*) = nullptr;
-    i64 (*m__len__)(VM* vm, PyObject*) = nullptr;
-    PyObject* (*m__iter__)(VM* vm, PyObject*) = nullptr;
-    unsigned (*m__next__)(VM* vm, PyObject*) = nullptr;
-    PyObject* (*m__neg__)(VM* vm, PyObject*) = nullptr;
-    PyObject* (*m__invert__)(VM* vm, PyObject*) = nullptr;
+    Str (*m__repr__)(VM* vm, PyVar) = nullptr;
+    Str (*m__str__)(VM* vm, PyVar) = nullptr;
+    i64 (*m__hash__)(VM* vm, PyVar) = nullptr;
+    i64 (*m__len__)(VM* vm, PyVar) = nullptr;
+    PyVar (*m__iter__)(VM* vm, PyVar) = nullptr;
+    unsigned (*m__next__)(VM* vm, PyVar) = nullptr;
+    PyVar (*m__neg__)(VM* vm, PyVar) = nullptr;
+    PyVar (*m__invert__)(VM* vm, PyVar) = nullptr;
 
     BinaryFuncC m__eq__ = nullptr;
     BinaryFuncC m__lt__ = nullptr;
@@ -84,14 +84,14 @@ struct PyTypeInfo{
     BinaryFuncC m__xor__ = nullptr;
 
     // indexer
-    PyObject* (*m__getitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
-    void (*m__setitem__)(VM* vm, PyObject*, PyObject*, PyObject*) = nullptr;
-    void (*m__delitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
+    PyVar (*m__getitem__)(VM* vm, PyVar, PyVar) = nullptr;
+    void (*m__setitem__)(VM* vm, PyVar, PyVar, PyVar) = nullptr;
+    void (*m__delitem__)(VM* vm, PyVar, PyVar) = nullptr;
 
     // attributes
-    void (*m__setattr__)(VM* vm, PyObject*, StrName, PyObject*) = nullptr;
-    PyObject* (*m__getattr__)(VM* vm, PyObject*, StrName) = nullptr;
-    bool (*m__delattr__)(VM* vm, PyObject*, StrName) = nullptr;
+    void (*m__setattr__)(VM* vm, PyVar, StrName, PyVar) = nullptr;
+    PyVar (*m__getattr__)(VM* vm, PyVar, StrName) = nullptr;
+    bool (*m__delattr__)(VM* vm, PyVar, StrName) = nullptr;
 
     // backdoors
     void (*on_end_subclass)(VM* vm, PyTypeInfo*) = nullptr;
@@ -138,25 +138,25 @@ public:
     std::map<StrName, Str> _lazy_modules;              // lazy loaded modules
 
     struct{
-        PyObject* error;
+        PyVar error;
         stack_no_copy<ArgsView> s_view;
     } __c;
 
-    PyObject *None, *True, *False, *NotImplemented;
-    PyObject *StopIteration, *Ellipsis;
-    PyObject *builtins, *_main;
+    PyVar None, True, False, NotImplemented;
+    PyVar StopIteration, Ellipsis;
+    PyVar builtins, _main;
 
     // typeid -> Type
     std::map<const std::type_index, Type> _cxx_typeid_map;
     // this is for repr() recursion detection (no need to mark)
-    std::set<PyObject*> _repr_recursion_set;
+    std::set<PyVar> _repr_recursion_set;
 
     ImportContext __import_context;
-    PyObject* __last_exception;
-    PyObject* __curr_class; 
-    PyObject* __cached_object_new;
+    PyVar __last_exception;
+    PyVar __curr_class; 
+    PyVar __cached_object_new;
     std::map<std::string_view, CodeObject_> __cached_codes;
-    std::map<std::string_view, PyObject*> __cached_op_funcs;
+    std::map<std::string_view, PyVar> __cached_op_funcs;
     FuncDecl_ __dynamic_func_decl;
 
 #if PK_ENABLE_PROFILER
@@ -186,38 +186,38 @@ public:
     VM(bool enable_os=true);
 
 #if PK_REGION("Python Equivalents")
-    Str py_str(PyObject* obj);                              // x -> str(x)
-    Str py_repr(PyObject* obj);                             // x -> repr(x)
-    Str py_json(PyObject* obj);                             // x -> json.dumps(x)
-
-    PyObject* py_iter(PyObject* obj);                       // x -> iter(x)
-    PyObject* py_next(PyObject*);                           // x -> next(x)
-    PyObject* _py_next(const PyTypeInfo*, PyObject*);       // x -> next(x) with type info cache
-    PyObject* py_import(Str path, bool throw_err=true);     // x -> __import__(x)
-    PyObject* py_negate(PyObject* obj);                     // x -> -x
-
-    List py_list(PyObject*);                                // x -> list(x)
-    bool py_callable(PyObject* obj);                        // x -> callable(x)
-    bool py_bool(PyObject* obj);                            // x -> bool(x)
-    i64 py_hash(PyObject* obj);                             // x -> hash(x)
-
-    bool py_eq(PyObject* lhs, PyObject* rhs);               // (lhs, rhs) -> lhs == rhs
-    bool py_lt(PyObject* lhs, PyObject* rhs);               // (lhs, rhs) -> lhs < rhs
-    bool py_le(PyObject* lhs, PyObject* rhs);               // (lhs, rhs) -> lhs <= rhs
-    bool py_gt(PyObject* lhs, PyObject* rhs);               // (lhs, rhs) -> lhs > rhs
-    bool py_ge(PyObject* lhs, PyObject* rhs);               // (lhs, rhs) -> lhs >= rhs
-    bool py_ne(PyObject* lhs, PyObject* rhs){               // (lhs, rhs) -> lhs != rhs
+    Str py_str(PyVar obj);                              // x -> str(x)
+    Str py_repr(PyVar obj);                             // x -> repr(x)
+    Str py_json(PyVar obj);                             // x -> json.dumps(x)
+
+    PyVar py_iter(PyVar obj);                           // x -> iter(x)
+    PyVar py_next(PyVar);                               // x -> next(x)
+    PyVar _py_next(const PyTypeInfo*, PyVar);           // x -> next(x) with type info cache
+    PyVar py_import(Str path, bool throw_err=true);     // x -> __import__(x)
+    PyVar py_negate(PyVar obj);                         // x -> -x
+
+    List py_list(PyVar);                                // x -> list(x)
+    bool py_callable(PyVar obj);                        // x -> callable(x)
+    bool py_bool(PyVar obj);                            // x -> bool(x)
+    i64 py_hash(PyVar obj);                             // x -> hash(x)
+
+    bool py_eq(PyVar lhs, PyVar rhs);                   // (lhs, rhs) -> lhs == rhs
+    bool py_lt(PyVar lhs, PyVar rhs);                   // (lhs, rhs) -> lhs < rhs
+    bool py_le(PyVar lhs, PyVar rhs);                   // (lhs, rhs) -> lhs <= rhs
+    bool py_gt(PyVar lhs, PyVar rhs);                   // (lhs, rhs) -> lhs > rhs
+    bool py_ge(PyVar lhs, PyVar rhs);                   // (lhs, rhs) -> lhs >= rhs
+    bool py_ne(PyVar lhs, PyVar rhs){                   // (lhs, rhs) -> lhs != rhs
         return !py_eq(lhs, rhs);
     }
 
-    PyObject* py_op(std::string_view name);                 // (name) -> operator.name
+    PyVar py_op(std::string_view name);                 // (name) -> operator.name
 
-    void py_exec(std::string_view, PyObject*, PyObject*);       // exec(source, globals, locals)
-    PyObject* py_eval(std::string_view, PyObject*, PyObject*);  // eval(source, globals, locals)
+    void py_exec(std::string_view, PyVar, PyVar);       // exec(source, globals, locals)
+    PyVar py_eval(std::string_view, PyVar, PyVar);      // eval(source, globals, locals)
 #endif
 
 #if PK_REGION("Utility Methods")
-    ArgsView cast_array_view(PyObject* obj);
+    ArgsView cast_array_view(PyVar obj);
     void set_main_argv(int argc, char** argv);
     i64 normalized_index(i64 index, int size);
     Str disassemble(CodeObject_ co);
@@ -225,47 +225,47 @@ public:
 #endif
 
 #if PK_REGION("Name Lookup Methods")
-    PyObject* find_name_in_mro(Type cls, StrName name);
-    PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false);
-    PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true);
-    void delattr(PyObject* obj, StrName name);
-    void setattr(PyObject* obj, StrName name, PyObject* value);
+    PyVar find_name_in_mro(Type cls, StrName name);
+    PyVar get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_err=true, bool fallback=false);
+    PyVar getattr(PyVar obj, StrName name, bool throw_err=true);
+    void delattr(PyVar obj, StrName name);
+    void setattr(PyVar obj, StrName name, PyVar value);
 #endif
 
 #if PK_REGION("Source Execution Methods")
     CodeObject_ compile(std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
     Str precompile(std::string_view source, const Str& filename, CompileMode mode);
-    PyObject* exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module=nullptr);
-    PyObject* exec(std::string_view source);
-    PyObject* eval(std::string_view source);
+    PyVar exec(std::string_view source, Str filename, CompileMode mode, PyVar _module=nullptr);
+    PyVar exec(std::string_view source);
+    PyVar eval(std::string_view source);
 
     template<typename ...Args>
-    PyObject* _exec(Args&&... args){
+    PyVar _exec(Args&&... args){
         callstack.emplace(s_data._sp, std::forward<Args>(args)...);
         return __run_top_frame();
     }
 #endif
 
 #if PK_REGION("Invocation Methods")
-    PyObject* vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
+    PyVar vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
 
     template<typename... Args>
-    PyObject* call(PyObject* callable, Args&&... args){
+    PyVar call(PyVar callable, Args&&... args){
         PUSH(callable); PUSH(PY_NULL);
         __push_varargs(args...);
         return vectorcall(sizeof...(args));
     }
 
     template<typename... Args>
-    PyObject* call_method(PyObject* self, PyObject* callable, Args&&... args){
+    PyVar call_method(PyVar self, PyVar callable, Args&&... args){
         PUSH(callable); PUSH(self);
         __push_varargs(args...);
         return vectorcall(sizeof...(args));
     }
 
     template<typename... Args>
-    PyObject* call_method(PyObject* self, StrName name, Args&&... args){
-        PyObject* callable = get_unbound_method(self, name, &self);
+    PyVar call_method(PyVar self, StrName name, Args&&... args){
+        PyVar callable = get_unbound_method(self, name, &self);
         return call_method(self, callable, args...);
     }
 #endif
@@ -276,16 +276,16 @@ public:
 #endif
 
 #if PK_REGION("Magic Bindings")
-    void bind__repr__(Type type, Str (*f)(VM*, PyObject*));
-    void bind__str__(Type type, Str (*f)(VM*, PyObject*));
-    void bind__iter__(Type type, PyObject* (*f)(VM*, PyObject*));
+    void bind__repr__(Type type, Str (*f)(VM*, PyVar));
+    void bind__str__(Type type, Str (*f)(VM*, PyVar));
+    void bind__iter__(Type type, PyVar (*f)(VM*, PyVar));
 
-    void bind__next__(Type type, unsigned (*f)(VM*, PyObject*));
-    [[deprecated]] void bind__next__(Type type, PyObject* (*f)(VM*, PyObject*));
-    void bind__neg__(Type type, PyObject* (*f)(VM*, PyObject*));
-    void bind__invert__(Type type, PyObject* (*f)(VM*, PyObject*));
-    void bind__hash__(Type type, i64 (*f)(VM* vm, PyObject*));
-    void bind__len__(Type type, i64 (*f)(VM* vm, PyObject*));
+    void bind__next__(Type type, unsigned (*f)(VM*, PyVar));
+    [[deprecated]] void bind__next__(Type type, PyVar (*f)(VM*, PyVar));
+    void bind__neg__(Type type, PyVar (*f)(VM*, PyVar));
+    void bind__invert__(Type type, PyVar (*f)(VM*, PyVar));
+    void bind__hash__(Type type, i64 (*f)(VM* vm, PyVar));
+    void bind__len__(Type type, i64 (*f)(VM* vm, PyVar));
 
     void bind__eq__(Type type, BinaryFuncC f);
     void bind__lt__(Type type, BinaryFuncC f);
@@ -309,35 +309,35 @@ public:
     void bind__or__(Type type, BinaryFuncC f);
     void bind__xor__(Type type, BinaryFuncC f);
 
-    void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*));
-    void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*));
-    void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*));
+    void bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar));
+    void bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar));
+    void bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar));
 #endif
 
 #if PK_REGION("General Bindings")
-    PyObject* bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT);
-    PyObject* bind_func(Type type, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT){
+    PyVar bind_func(PyVar obj, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT);
+    PyVar bind_func(Type type, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT){
         return bind_func(_t(type), name, argc, fn, std::move(userdata), bt);
     }
-    PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
+    PyVar bind_property(PyVar, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
     template<typename T, typename F, bool ReadOnly=false>
-    PyObject* bind_field(PyObject*, const char*, F T::*);
+    PyVar bind_field(PyVar, const char*, F T::*);
 
-    PyObject* bind(PyObject*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
+    PyVar bind(PyVar, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
     template<typename Ret, typename... Params>
-    PyObject* bind(PyObject*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
+    PyVar bind(PyVar, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
     template<typename Ret, typename T, typename... Params>
-    PyObject* bind(PyObject*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
+    PyVar bind(PyVar, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
 
-    PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
+    PyVar bind(PyVar, const char*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
     template<typename Ret, typename... Params>
-    PyObject* bind(PyObject*, const char*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
+    PyVar bind(PyVar, const char*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
     template<typename Ret, typename T, typename... Params>
-    PyObject* bind(PyObject*, const char*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
+    PyVar bind(PyVar, const char*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
 #endif
 
 #if PK_REGION("Error Reporting Methods")
-    void _error(PyObject*);
+    void _error(PyVar);
     void StackOverflowError() { __builtin_error("StackOverflowError"); }
     void IOError(const Str& msg) { __builtin_error("IOError", msg); }
     void NotImplementedError(){ __builtin_error("NotImplementedError"); }
@@ -350,44 +350,44 @@ public:
     void ZeroDivisionError(){ __builtin_error("ZeroDivisionError", "division by zero"); }
     void NameError(StrName name){ __builtin_error("NameError", _S("name ", name.escape() + " is not defined")); }
     void UnboundLocalError(StrName name){ __builtin_error("UnboundLocalError", _S("local variable ", name.escape() + " referenced before assignment")); }
-    void KeyError(PyObject* obj){ __builtin_error("KeyError", obj); }
+    void KeyError(PyVar obj){ __builtin_error("KeyError", obj); }
     void ImportError(const Str& msg){ __builtin_error("ImportError", msg); }
     void AssertionError(const Str& msg){ __builtin_error("AssertionError", msg); }
     void AssertionError(){ __builtin_error("AssertionError"); }
-    void BinaryOptError(const char* op, PyObject* _0, PyObject* _1);
-    void AttributeError(PyObject* obj, StrName name);
+    void BinaryOptError(const char* op, PyVar _0, PyVar _1);
+    void AttributeError(PyVar obj, StrName name);
     void AttributeError(const Str& msg){ __builtin_error("AttributeError", msg); }
 #endif
 
 #if PK_REGION("Type Checking Methods")
-    bool isinstance(PyObject* obj, Type base);
+    bool isinstance(PyVar obj, Type base);
     bool issubclass(Type cls, Type base);
-    void check_type(PyObject* obj, Type type){ if(!is_type(obj, type)) TypeError(type, _tp(obj)); }
-    void check_compatible_type(PyObject* obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); }
+    void check_type(PyVar obj, Type type){ if(!is_type(obj, type)) TypeError(type, _tp(obj)); }
+    void check_compatible_type(PyVar obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); }
 
-    Type _tp(PyObject* obj){ return is_small_int(obj) ? tp_int : obj->type; }
-    const PyTypeInfo* _tp_info(PyObject* obj) { return &_all_types[_tp(obj)]; }
+    Type _tp(PyVar obj){ return is_small_int(obj) ? tp_int : obj->type; }
+    const PyTypeInfo* _tp_info(PyVar obj) { return &_all_types[_tp(obj)]; }
     const PyTypeInfo* _tp_info(Type type) { return &_all_types[type]; }
-    PyObject* _t(PyObject* obj){ return _all_types[_tp(obj)].obj; }
-    PyObject* _t(Type type){ return _all_types[type].obj; }
+    PyVar _t(PyVar obj){ return _all_types[_tp(obj)].obj; }
+    PyVar _t(Type type){ return _all_types[type].obj; }
 #endif
 
 #if PK_REGION("User Type Registration")
-    PyObject* new_module(Str name, Str package="");
-    PyObject* new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled=true);
+    PyVar new_module(Str name, Str package="");
+    PyVar new_type_object(PyVar mod, StrName name, Type base, bool subclass_enabled=true);
 
     template<typename T>
     Type _tp_user(){ return _find_type_in_cxx_typeid_map<T>(); }
     template<typename T>
-    bool is_user_type(PyObject* obj){ return _tp(obj) == _tp_user<T>(); }
+    bool is_user_type(PyVar obj){ return _tp(obj) == _tp_user<T>(); }
 
     template<typename T>
-    PyObject* register_user_class(PyObject*, StrName, RegisterFunc, Type base=tp_object, bool subclass_enabled=false);
+    PyVar register_user_class(PyVar, StrName, RegisterFunc, Type base=tp_object, bool subclass_enabled=false);
     template<typename T>
-    PyObject* register_user_class(PyObject*, StrName, Type base=tp_object, bool subclass_enabled=false);
+    PyVar register_user_class(PyVar, StrName, Type base=tp_object, bool subclass_enabled=false);
 
     template<typename T, typename ...Args>
-    PyObject* new_user_object(Args&&... args){
+    PyVar new_user_object(Args&&... args){
         return heap.gcnew<T>(_tp_user<T>(), std::forward<Args>(args)...);
     }
 #endif
@@ -413,29 +413,29 @@ public:
 #if PK_DEBUG_CEVAL_STEP
     void __log_s_data(const char* title = nullptr);
 #endif
-    PyObject* __py_exec_internal(const CodeObject_& code, PyObject* globals, PyObject* locals);
+    PyVar __py_exec_internal(const CodeObject_& code, PyVar globals, PyVar locals);
     void __breakpoint();
-    PyObject* __format_object(PyObject*, Str);
-    PyObject* __run_top_frame();
+    PyVar __format_object(PyVar, Str);
+    PyVar __run_top_frame();
     void __pop_frame();
-    PyObject* __py_generator(Frame&& frame, ArgsView buffer);
+    PyVar __py_generator(Frame&& frame, ArgsView buffer);
     void __op_unpack_sequence(uint16_t arg);
-    void __prepare_py_call(PyObject**, ArgsView, ArgsView, const FuncDecl_&);
+    void __prepare_py_call(PyVar*, ArgsView, ArgsView, const FuncDecl_&);
     void __unpack_as_list(ArgsView args, List& list);
     void __unpack_as_dict(ArgsView args, Dict& dict);
     void __raise_exc(bool re_raise=false);
     void __init_builtin_types();
     void __post_init_builtin_types();
     void __builtin_error(StrName type);
-    void __builtin_error(StrName type, PyObject* arg);
+    void __builtin_error(StrName type, PyVar arg);
     void __builtin_error(StrName type, const Str& msg);
     void __push_varargs(){}
-    void __push_varargs(PyObject* _0){ PUSH(_0); }
-    void __push_varargs(PyObject* _0, PyObject* _1){ PUSH(_0); PUSH(_1); }
-    void __push_varargs(PyObject* _0, PyObject* _1, PyObject* _2){ PUSH(_0); PUSH(_1); PUSH(_2); }
-    void __push_varargs(PyObject* _0, PyObject* _1, PyObject* _2, PyObject* _3){ PUSH(_0); PUSH(_1); PUSH(_2); PUSH(_3); }
-    PyObject* __pack_next_retval(unsigned);
-    PyObject* __minmax_reduce(bool (VM::*op)(PyObject*, PyObject*), PyObject* args, PyObject* key);
+    void __push_varargs(PyVar _0){ PUSH(_0); }
+    void __push_varargs(PyVar _0, PyVar _1){ PUSH(_0); PUSH(_1); }
+    void __push_varargs(PyVar _0, PyVar _1, PyVar _2){ PUSH(_0); PUSH(_1); PUSH(_2); }
+    void __push_varargs(PyVar _0, PyVar _1, PyVar _2, PyVar _3){ PUSH(_0); PUSH(_1); PUSH(_2); PUSH(_3); }
+    PyVar __pack_next_retval(unsigned);
+    PyVar __minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key);
 };
 
 
@@ -464,10 +464,10 @@ template<> constexpr Type _find_type_in_const_cxx_typeid_map<StaticMethod>(){ re
 template<> constexpr Type _find_type_in_const_cxx_typeid_map<ClassMethod>(){ return VM::tp_classmethod; }
 
 template<typename __T>
-PyObject* py_var(VM* vm, __T&& value){
+PyVar py_var(VM* vm, __T&& value){
     using T = std::decay_t<__T>;
 
-    static_assert(!std::is_same_v<T, PyObject*>, "py_var(VM*, PyObject*) is not allowed");
+    static_assert(!std::is_same_v<T, PyVar>, "py_var(VM*, PyVar) is not allowed");
 
     if constexpr(std::is_same_v<T, const char*> || std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view>){
         // str (shortcuts)
@@ -483,7 +483,7 @@ PyObject* py_var(VM* vm, __T&& value){
         i64 val = static_cast<i64>(std::forward<__T>(value));
         if(val >= Number::kMinSmallInt && val <= Number::kMaxSmallInt){
             val = (val << 2) | 0b10;
-            return reinterpret_cast<PyObject*>(val);
+            return reinterpret_cast<PyVar>(val);
         }else{
             return vm->heap.gcnew<i64>(vm->tp_int, val);
         }
@@ -504,7 +504,7 @@ PyObject* py_var(VM* vm, __T&& value){
 }
 
 template<typename __T, bool with_check>
-__T _py_cast__internal(VM* vm, PyObject* obj) {
+__T _py_cast__internal(VM* vm, PyVar obj) {
     static_assert(!std::is_rvalue_reference_v<__T>, "rvalue reference is not allowed");
 
     using T = std::decay_t<__T>;
@@ -569,13 +569,13 @@ __T _py_cast__internal(VM* vm, PyObject* obj) {
 }
 
 template<typename __T>
-__T  py_cast(VM* vm, PyObject* obj) { return _py_cast__internal<__T, true>(vm, obj); }
+__T  py_cast(VM* vm, PyVar obj) { return _py_cast__internal<__T, true>(vm, obj); }
 template<typename __T>
-__T _py_cast(VM* vm, PyObject* obj) { return _py_cast__internal<__T, false>(vm, obj); }
+__T _py_cast(VM* vm, PyVar obj) { return _py_cast__internal<__T, false>(vm, obj); }
 
 template<typename T>
-PyObject* VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled){
-    PyObject* type = new_type_object(mod, name, base, subclass_enabled);
+PyVar VM::register_user_class(PyVar mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled){
+    PyVar type = new_type_object(mod, name, base, subclass_enabled);
     mod->attr().set(name, type);
     _cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type);
     _register(this, mod, type);
@@ -593,7 +593,7 @@ PyObject* VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _reg
 }
 
 template<typename T>
-PyObject* VM::register_user_class(PyObject* mod, StrName name, Type base, bool subclass_enabled){
+PyVar VM::register_user_class(PyVar mod, StrName name, Type base, bool subclass_enabled){
     return register_user_class<T>(mod, name, &T::_register, base, subclass_enabled);
 }