replace PyObject* with PyVar

This commit is contained in:
blueloveTH 2024-05-12 20:04:40 +08:00
parent 60f248b245
commit 7fd4e3fdfb
15 changed files with 286 additions and 286 deletions

View File

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

View File

@ -7,7 +7,7 @@ namespace pkpy {
#define PY_CLASS(T, mod, name) \ #define PY_CLASS(T, mod, name) \
[[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \ [[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \
[[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); \ return vm->register_user_class<T>(mod, #name, base); \
} }
@ -32,13 +32,13 @@ struct VoidP{
return ss.str(); 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) \ #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); \ 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); \ 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(const Struct& other): Struct(other.p, other.size){}
~Struct(){ if(p!=_inlined) free(p); } ~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); static_assert(sizeof(Py_<Struct>) <= 64);
@ -92,7 +92,7 @@ static_assert(sizeof(Py_<Tuple>) <= 64);
/***********************************************/ /***********************************************/
template<typename Tp> 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>); static_assert(std::is_pointer_v<Tp>);
if(var == vm->None) return nullptr; // None can be casted to any pointer implicitly if(var == vm->None) return nullptr; // None can be casted to any pointer implicitly
VoidP& p = CAST(VoidP&, var); VoidP& p = CAST(VoidP&, var);

View File

@ -65,7 +65,7 @@ struct CodeObject {
std::vector<int> iblocks; // block index for each bytecode std::vector<int> iblocks; // block index for each bytecode
std::vector<LineInfo> lines; 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 small_vector_2<StrName, 8> varnames; // local variables
NameDictInt varnames_inv; NameDictInt varnames_inv;
@ -96,7 +96,7 @@ struct FuncDecl {
struct KwArg { struct KwArg {
int index; // index in co->varnames int index; // index in co->varnames
StrName key; // name of this argument StrName key; // name of this argument
PyObject* value; // default value PyVar value; // default value
}; };
CodeObject_ code; // code object of this function CodeObject_ code; // code object of this function
@ -113,7 +113,7 @@ struct FuncDecl {
NameDictInt kw_to_index; 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); kw_to_index.set(key, index);
kwargs.push_back(KwArg{index, key, value}); 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)) {} 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; 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{ struct Function{
FuncDecl_ decl; FuncDecl_ decl;
PyObject* _module; // weak ref PyVar _module; // weak ref
PyObject* _class; // weak ref PyVar _class; // weak ref
NameDict_ _closure; 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) {} decl(decl), _module(_module), _class(_class), _closure(_closure) {}
}; };
@ -172,7 +172,7 @@ struct Py_<NativeFunc> final: PyObject {
}; };
template<typename T> 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>>); static_assert(std::is_same_v<T, std::decay_t<T>>);
int offset = p[-1] != PY_NULL ? -1 : -2; int offset = p[-1] != PY_NULL ? -1 : -2;
return PK_OBJ_GET(NativeFunc, p[offset])._userdata.cast<T>(); return PK_OBJ_GET(NativeFunc, p[offset])._userdata.cast<T>();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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