mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
replace PyObject*
with PyVar
This commit is contained in:
parent
60f248b245
commit
7fd4e3fdfb
@ -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); \
|
||||||
|
@ -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);
|
||||||
|
@ -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>();
|
||||||
|
@ -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); }
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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); }
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
@ -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 {
|
||||||
|
@ -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>;
|
||||||
|
|
||||||
|
@ -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
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user