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{
|
||||
struct NativeProxyFuncCBase {
|
||||
virtual PyObject* operator()(VM* vm, ArgsView args) = 0;
|
||||
virtual PyVar operator()(VM* vm, ArgsView args) = 0;
|
||||
};
|
||||
|
||||
template<typename Ret, typename... Params>
|
||||
@ -15,13 +15,13 @@ struct NativeProxyFuncC final: NativeProxyFuncCBase {
|
||||
_Fp func;
|
||||
NativeProxyFuncC(_Fp func) : func(func) {}
|
||||
|
||||
PyObject* operator()(VM* vm, ArgsView args) override {
|
||||
PyVar operator()(VM* vm, ArgsView args) override {
|
||||
PK_DEBUG_ASSERT(args.size() == N);
|
||||
return call<Ret>(vm, args, std::make_index_sequence<N>());
|
||||
}
|
||||
|
||||
template<typename __Ret, size_t... Is>
|
||||
PyObject* call(VM* vm, ArgsView args, std::index_sequence<Is...>){
|
||||
PyVar call(VM* vm, ArgsView args, std::index_sequence<Is...>){
|
||||
if constexpr(std::is_void_v<__Ret>){
|
||||
func(py_cast<Params>(vm, args[Is])...);
|
||||
return vm->None;
|
||||
@ -39,13 +39,13 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase {
|
||||
_Fp func;
|
||||
NativeProxyMethodC(_Fp func) : func(func) {}
|
||||
|
||||
PyObject* operator()(VM* vm, ArgsView args) override {
|
||||
PyVar operator()(VM* vm, ArgsView args) override {
|
||||
PK_DEBUG_ASSERT(args.size() == N+1);
|
||||
return call<Ret>(vm, args, std::make_index_sequence<N>());
|
||||
}
|
||||
|
||||
template<typename __Ret, size_t... Is>
|
||||
PyObject* call(VM* vm, ArgsView args, std::index_sequence<Is...>){
|
||||
PyVar call(VM* vm, ArgsView args, std::index_sequence<Is...>){
|
||||
T& self = PK_OBJ_GET(T, args[0]); // use unsafe cast for derived classes
|
||||
if constexpr(std::is_void_v<__Ret>){
|
||||
(self.*func)(py_cast<Params>(vm, args[Is+1])...);
|
||||
@ -57,48 +57,48 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase {
|
||||
}
|
||||
};
|
||||
/*****************************************************************/
|
||||
inline PyObject* __proxy_wrapper(VM* vm, ArgsView args){
|
||||
inline PyVar __proxy_wrapper(VM* vm, ArgsView args){
|
||||
NativeProxyFuncCBase* pf = lambda_get_userdata<NativeProxyFuncCBase*>(args.begin());
|
||||
return (*pf)(vm, args);
|
||||
}
|
||||
|
||||
template<typename Ret, typename... Params>
|
||||
PyObject* VM::bind(PyObject* obj, const char* sig, Ret(*func)(Params...), BindType bt){
|
||||
PyVar VM::bind(PyVar obj, const char* sig, Ret(*func)(Params...), BindType bt){
|
||||
NativeProxyFuncCBase* proxy = new NativeProxyFuncC<Ret, Params...>(func);
|
||||
return vm->bind(obj, sig, __proxy_wrapper, proxy, bt);
|
||||
}
|
||||
|
||||
template<typename Ret, typename T, typename... Params>
|
||||
PyObject* VM::bind(PyObject* obj, const char* sig, Ret(T::*func)(Params...), BindType bt){
|
||||
PyVar VM::bind(PyVar obj, const char* sig, Ret(T::*func)(Params...), BindType bt){
|
||||
NativeProxyFuncCBase* proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
|
||||
return vm->bind(obj, sig, __proxy_wrapper, proxy, bt);
|
||||
}
|
||||
|
||||
template<typename Ret, typename... Params>
|
||||
PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Ret(*func)(Params...), BindType bt){
|
||||
PyVar VM::bind(PyVar obj, const char* sig, const char* docstring, Ret(*func)(Params...), BindType bt){
|
||||
NativeProxyFuncCBase* proxy = new NativeProxyFuncC<Ret, Params...>(func);
|
||||
return vm->bind(obj, sig, docstring, __proxy_wrapper, proxy, bt);
|
||||
}
|
||||
|
||||
template<typename Ret, typename T, typename... Params>
|
||||
PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Ret(T::*func)(Params...), BindType bt){
|
||||
PyVar VM::bind(PyVar obj, const char* sig, const char* docstring, Ret(T::*func)(Params...), BindType bt){
|
||||
NativeProxyFuncCBase* proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
|
||||
return vm->bind(obj, sig, docstring, __proxy_wrapper, proxy, bt);
|
||||
}
|
||||
|
||||
template<typename T, typename F, bool ReadOnly>
|
||||
PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){
|
||||
PyVar VM::bind_field(PyVar obj, const char* name, F T::*field){
|
||||
static_assert(!std::is_reference_v<F>);
|
||||
PK_ASSERT(is_type(obj, tp_type));
|
||||
std::string_view name_sv(name); int pos = name_sv.find(':');
|
||||
if(pos > 0) name_sv = name_sv.substr(0, pos);
|
||||
auto fget = [](VM* vm, ArgsView args) -> PyObject*{
|
||||
auto fget = [](VM* vm, ArgsView args) -> PyVar{
|
||||
T& self = PK_OBJ_GET(T, args[0]);
|
||||
F T::*field = lambda_get_userdata<F T::*>(args.begin());
|
||||
return VAR(self.*field);
|
||||
};
|
||||
PyObject* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, field);
|
||||
PyObject* _1 = vm->None;
|
||||
PyVar _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, field);
|
||||
PyVar _1 = vm->None;
|
||||
if constexpr (!ReadOnly){
|
||||
auto fset = [](VM* vm, ArgsView args){
|
||||
T& self = PK_OBJ_GET(T, args[0]);
|
||||
@ -108,18 +108,18 @@ PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){
|
||||
};
|
||||
_1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, field);
|
||||
}
|
||||
PyObject* prop = VAR(Property(_0, _1));
|
||||
PyVar prop = VAR(Property(_0, _1));
|
||||
obj->attr().set(StrName(name_sv), prop);
|
||||
return prop;
|
||||
}
|
||||
|
||||
template<typename Ret, typename... Params>
|
||||
[[deprecated]] void _bind(VM* vm, PyObject* obj, const char* sig, Ret(*func)(Params...)){
|
||||
[[deprecated]] void _bind(VM* vm, PyVar obj, const char* sig, Ret(*func)(Params...)){
|
||||
return vm->bind(obj, sig, func);
|
||||
}
|
||||
|
||||
template<typename Ret, typename T, typename... Params>
|
||||
[[deprecated]] void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
|
||||
[[deprecated]] void _bind(VM* vm, PyVar obj, const char* sig, Ret(T::*func)(Params...)){
|
||||
return vm->bind(obj, sig, func);
|
||||
}
|
||||
/*****************************************************************/
|
||||
@ -168,7 +168,7 @@ template<typename Ret, typename T, typename... Params>
|
||||
vm->bind_func(type, "fromstruct", 1, [](VM* vm, ArgsView args){ \
|
||||
Struct& s = CAST(Struct&, args[0]); \
|
||||
if(s.size != sizeof(wT)) vm->ValueError("size mismatch"); \
|
||||
PyObject* obj = vm->new_user_object<wT>(); \
|
||||
PyVar obj = vm->new_user_object<wT>(); \
|
||||
memcpy(&_CAST(wT&, obj), s.p, sizeof(wT)); \
|
||||
return obj; \
|
||||
}, {}, BindType::STATICMETHOD); \
|
||||
@ -187,7 +187,7 @@ template<typename Ret, typename T, typename... Params>
|
||||
vm->bind_func(type, "sizeof", 1, [](VM* vm, ArgsView args){ \
|
||||
return VAR(sizeof(wT)); \
|
||||
}); \
|
||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
|
||||
vm->bind__eq__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){ \
|
||||
wT& self = _CAST(wT&, _0); \
|
||||
if(!vm->isinstance(_1, vm->_tp_user<wT>())) return vm->NotImplemented; \
|
||||
wT& other = _CAST(wT&, _1); \
|
||||
@ -195,13 +195,13 @@ template<typename Ret, typename T, typename... Params>
|
||||
}); \
|
||||
|
||||
#define PY_POINTER_SETGETITEM(T) \
|
||||
vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1){ \
|
||||
vm->bind__getitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1){ \
|
||||
VoidP& self = PK_OBJ_GET(VoidP, _0); \
|
||||
i64 i = CAST(i64, _1); \
|
||||
T* tgt = reinterpret_cast<T*>(self.ptr); \
|
||||
return VAR(tgt[i]); \
|
||||
}); \
|
||||
vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyObject* _0, PyObject* _1, PyObject* _2){ \
|
||||
vm->bind__setitem__(PK_OBJ_GET(Type, type), [](VM* vm, PyVar _0, PyVar _1, PyVar _2){ \
|
||||
VoidP& self = PK_OBJ_GET(VoidP, _0); \
|
||||
i64 i = CAST(i64, _1); \
|
||||
T* tgt = reinterpret_cast<T*>(self.ptr); \
|
||||
|
@ -7,7 +7,7 @@ namespace pkpy {
|
||||
|
||||
#define PY_CLASS(T, mod, name) \
|
||||
[[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \
|
||||
[[deprecated]] static PyObject* register_class(VM* vm, PyObject* mod, Type base=Type(0)) { \
|
||||
[[deprecated]] static PyVar register_class(VM* vm, PyVar mod, Type base=Type(0)) { \
|
||||
return vm->register_user_class<T>(mod, #name, base); \
|
||||
}
|
||||
|
||||
@ -32,13 +32,13 @@ struct VoidP{
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
};
|
||||
|
||||
#define POINTER_VAR(Tp, NAME) \
|
||||
inline PyObject* py_var(VM* vm, Tp val){ \
|
||||
inline PyVar py_var(VM* vm, Tp val){ \
|
||||
const static std::pair<StrName, StrName> P("c", NAME); \
|
||||
PyObject* type = vm->_modules[P.first]->attr(P.second); \
|
||||
PyVar type = vm->_modules[P.first]->attr(P.second); \
|
||||
return vm->heap.gcnew<VoidP>(PK_OBJ_GET(Type, type), val); \
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ struct Struct{
|
||||
Struct(const Struct& other): Struct(other.p, other.size){}
|
||||
~Struct(){ if(p!=_inlined) free(p); }
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
};
|
||||
|
||||
static_assert(sizeof(Py_<Struct>) <= 64);
|
||||
@ -92,7 +92,7 @@ static_assert(sizeof(Py_<Tuple>) <= 64);
|
||||
|
||||
/***********************************************/
|
||||
template<typename Tp>
|
||||
Tp to_void_p(VM* vm, PyObject* var){
|
||||
Tp to_void_p(VM* vm, PyVar var){
|
||||
static_assert(std::is_pointer_v<Tp>);
|
||||
if(var == vm->None) return nullptr; // None can be casted to any pointer implicitly
|
||||
VoidP& p = CAST(VoidP&, var);
|
||||
|
@ -65,7 +65,7 @@ struct CodeObject {
|
||||
std::vector<int> iblocks; // block index for each bytecode
|
||||
std::vector<LineInfo> lines;
|
||||
|
||||
small_vector_2<PyObject*, 8> consts; // constants
|
||||
small_vector_2<PyVar, 8> consts; // constants
|
||||
small_vector_2<StrName, 8> varnames; // local variables
|
||||
|
||||
NameDictInt varnames_inv;
|
||||
@ -96,7 +96,7 @@ struct FuncDecl {
|
||||
struct KwArg {
|
||||
int index; // index in co->varnames
|
||||
StrName key; // name of this argument
|
||||
PyObject* value; // default value
|
||||
PyVar value; // default value
|
||||
};
|
||||
CodeObject_ code; // code object of this function
|
||||
|
||||
@ -113,7 +113,7 @@ struct FuncDecl {
|
||||
|
||||
NameDictInt kw_to_index;
|
||||
|
||||
void add_kwarg(int index, StrName key, PyObject* value){
|
||||
void add_kwarg(int index, StrName key, PyVar value){
|
||||
kw_to_index.set(key, index);
|
||||
kwargs.push_back(KwArg{index, key, value});
|
||||
}
|
||||
@ -131,16 +131,16 @@ struct NativeFunc {
|
||||
NativeFunc(NativeFuncC f, FuncDecl_ decl, any userdata={}): f(f), argc(-1), decl(decl), _userdata(std::move(userdata)) {}
|
||||
|
||||
void check_size(VM* vm, ArgsView args) const;
|
||||
PyObject* call(VM* vm, ArgsView args) const { return f(vm, args); }
|
||||
PyVar call(VM* vm, ArgsView args) const { return f(vm, args); }
|
||||
};
|
||||
|
||||
struct Function{
|
||||
FuncDecl_ decl;
|
||||
PyObject* _module; // weak ref
|
||||
PyObject* _class; // weak ref
|
||||
PyVar _module; // weak ref
|
||||
PyVar _class; // weak ref
|
||||
NameDict_ _closure;
|
||||
|
||||
explicit Function(FuncDecl_ decl, PyObject* _module, PyObject* _class, NameDict_ _closure):
|
||||
explicit Function(FuncDecl_ decl, PyVar _module, PyVar _class, NameDict_ _closure):
|
||||
decl(decl), _module(_module), _class(_class), _closure(_closure) {}
|
||||
};
|
||||
|
||||
@ -172,7 +172,7 @@ struct Py_<NativeFunc> final: PyObject {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T& lambda_get_userdata(PyObject** p){
|
||||
T& lambda_get_userdata(PyVar* p){
|
||||
static_assert(std::is_same_v<T, std::decay_t<T>>);
|
||||
int offset = p[-1] != PY_NULL ? -1 : -2;
|
||||
return PK_OBJ_GET(NativeFunc, p[offset])._userdata.cast<T>();
|
||||
|
@ -112,8 +112,8 @@ class Compiler {
|
||||
void _compile_f_args(FuncDecl_ decl, bool enable_type_hints);
|
||||
void compile_function(const Expr_vector& decorators={});
|
||||
|
||||
PyObject* to_object(const TokenValue& value);
|
||||
PyObject* read_literal();
|
||||
PyVar to_object(const TokenValue& value);
|
||||
PyVar read_literal();
|
||||
|
||||
void SyntaxError(Str msg){ lexer.throw_err("SyntaxError", msg, err().line, err().start); }
|
||||
void SyntaxError(){ lexer.throw_err("SyntaxError", "invalid syntax", err().line, err().start); }
|
||||
|
@ -9,8 +9,8 @@ namespace pkpy{
|
||||
|
||||
struct Dict{
|
||||
struct Item{
|
||||
PyObject* first;
|
||||
PyObject* second;
|
||||
PyVar first;
|
||||
PyVar second;
|
||||
};
|
||||
|
||||
struct ItemNode{
|
||||
@ -41,16 +41,16 @@ struct Dict{
|
||||
|
||||
int size() const { return _size; }
|
||||
|
||||
void _probe_0(PyObject* key, bool& ok, int& i) const;
|
||||
void _probe_1(PyObject* key, bool& ok, int& i) const;
|
||||
void _probe_0(PyVar key, bool& ok, int& i) const;
|
||||
void _probe_1(PyVar key, bool& ok, int& i) const;
|
||||
|
||||
void set(PyObject* key, PyObject* val);
|
||||
void set(PyVar key, PyVar val);
|
||||
void _rehash();
|
||||
|
||||
PyObject* try_get(PyObject* key) const;
|
||||
PyVar try_get(PyVar key) const;
|
||||
|
||||
bool contains(PyObject* key) const;
|
||||
bool erase(PyObject* key);
|
||||
bool contains(PyVar key) const;
|
||||
bool erase(PyVar key);
|
||||
void update(const Dict& other);
|
||||
|
||||
template<typename __Func>
|
||||
|
@ -62,12 +62,12 @@ struct Exception {
|
||||
int _ip_on_error;
|
||||
void* _code_on_error;
|
||||
|
||||
PyObject* _self; // weak reference
|
||||
PyVar _self; // weak reference
|
||||
|
||||
stack<ExceptionLine> stacktrace;
|
||||
Exception(StrName type): type(type), is_re(true), _ip_on_error(-1), _code_on_error(nullptr), _self(nullptr) {}
|
||||
|
||||
PyObject* self() const{
|
||||
PyVar self() const{
|
||||
PK_ASSERT(_self != nullptr);
|
||||
return _self;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ struct CodeEmitContext{
|
||||
void patch_jump(int index);
|
||||
bool add_label(StrName name);
|
||||
int add_varname(StrName name);
|
||||
int add_const(PyObject*);
|
||||
int add_const(PyVar);
|
||||
int add_const_string(std::string_view);
|
||||
int add_func_decl(FuncDecl_ decl);
|
||||
void emit_store_name(NameScope scope, StrName name, int line);
|
||||
|
@ -12,55 +12,55 @@ namespace pkpy{
|
||||
struct FastLocals{
|
||||
// this is a weak reference
|
||||
const CodeObject* co;
|
||||
PyObject** a;
|
||||
PyVar* a;
|
||||
|
||||
int size() const{ return co->varnames.size();}
|
||||
|
||||
PyObject*& operator[](int i){ return a[i]; }
|
||||
PyObject* operator[](int i) const { return a[i]; }
|
||||
PyVar& operator[](int i){ return a[i]; }
|
||||
PyVar operator[](int i) const { return a[i]; }
|
||||
|
||||
FastLocals(const CodeObject* co, PyObject** a): co(co), a(a) {}
|
||||
FastLocals(const CodeObject* co, PyVar* a): co(co), a(a) {}
|
||||
|
||||
PyObject** try_get_name(StrName name);
|
||||
PyVar* try_get_name(StrName name);
|
||||
NameDict_ to_namedict();
|
||||
|
||||
PyObject** begin() const { return a; }
|
||||
PyObject** end() const { return a + size(); }
|
||||
PyVar* begin() const { return a; }
|
||||
PyVar* end() const { return a + size(); }
|
||||
};
|
||||
|
||||
struct ValueStack {
|
||||
// We allocate extra PK_VM_STACK_SIZE/128 places to keep `_sp` valid when `is_overflow() == true`.
|
||||
PyObject* _begin[PK_VM_STACK_SIZE + PK_VM_STACK_SIZE/128];
|
||||
PyObject** _sp;
|
||||
PyObject** _max_end;
|
||||
PyVar _begin[PK_VM_STACK_SIZE + PK_VM_STACK_SIZE/128];
|
||||
PyVar* _sp;
|
||||
PyVar* _max_end;
|
||||
|
||||
static constexpr size_t max_size() { return PK_VM_STACK_SIZE; }
|
||||
|
||||
ValueStack(): _sp(_begin), _max_end(_begin + PK_VM_STACK_SIZE) {}
|
||||
|
||||
PyObject*& top(){ return _sp[-1]; }
|
||||
PyObject* top() const { return _sp[-1]; }
|
||||
PyObject*& second(){ return _sp[-2]; }
|
||||
PyObject* second() const { return _sp[-2]; }
|
||||
PyObject*& third(){ return _sp[-3]; }
|
||||
PyObject* third() const { return _sp[-3]; }
|
||||
PyObject*& peek(int n){ return _sp[-n]; }
|
||||
PyObject* peek(int n) const { return _sp[-n]; }
|
||||
void push(PyObject* v){ *_sp++ = v; }
|
||||
PyVar& top(){ return _sp[-1]; }
|
||||
PyVar top() const { return _sp[-1]; }
|
||||
PyVar& second(){ return _sp[-2]; }
|
||||
PyVar second() const { return _sp[-2]; }
|
||||
PyVar& third(){ return _sp[-3]; }
|
||||
PyVar third() const { return _sp[-3]; }
|
||||
PyVar& peek(int n){ return _sp[-n]; }
|
||||
PyVar peek(int n) const { return _sp[-n]; }
|
||||
void push(PyVar v){ *_sp++ = v; }
|
||||
void pop(){ --_sp; }
|
||||
PyObject* popx(){ return *--_sp; }
|
||||
PyVar popx(){ return *--_sp; }
|
||||
ArgsView view(int n){ return ArgsView(_sp-n, _sp); }
|
||||
void shrink(int n){ _sp -= n; }
|
||||
int size() const { return _sp - _begin; }
|
||||
bool empty() const { return _sp == _begin; }
|
||||
PyObject** begin() { return _begin; }
|
||||
PyObject** end() { return _sp; }
|
||||
void reset(PyObject** sp) { _sp = sp; }
|
||||
PyVar* begin() { return _begin; }
|
||||
PyVar* end() { return _sp; }
|
||||
void reset(PyVar* sp) { _sp = sp; }
|
||||
void clear() { _sp = _begin; }
|
||||
bool is_overflow() const { return _sp >= _max_end; }
|
||||
|
||||
PyObject* operator[](int i) const { return _begin[i]; }
|
||||
PyObject*& operator[](int i) { return _begin[i]; }
|
||||
PyVar operator[](int i) const { return _begin[i]; }
|
||||
PyVar& operator[](int i) { return _begin[i]; }
|
||||
|
||||
ValueStack(const ValueStack&) = delete;
|
||||
ValueStack(ValueStack&&) = delete;
|
||||
@ -72,26 +72,26 @@ struct Frame {
|
||||
int _ip;
|
||||
int _next_ip;
|
||||
// This is for unwinding only, use `actual_sp_base()` for value stack access
|
||||
PyObject** _sp_base;
|
||||
PyVar* _sp_base;
|
||||
|
||||
const CodeObject* co;
|
||||
PyObject* _module;
|
||||
PyObject* _callable; // a function object or nullptr (global scope)
|
||||
PyVar _module;
|
||||
PyVar _callable; // a function object or nullptr (global scope)
|
||||
FastLocals _locals;
|
||||
|
||||
NameDict& f_globals() { return _module->attr(); }
|
||||
PyObject* f_closure_try_get(StrName name);
|
||||
PyVar f_closure_try_get(StrName name);
|
||||
|
||||
// function scope
|
||||
Frame(PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable, PyObject** _locals_base)
|
||||
Frame(PyVar* p0, const CodeObject* co, PyVar _module, PyVar _callable, PyVar* _locals_base)
|
||||
: _ip(-1), _next_ip(0), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(co, _locals_base) { }
|
||||
|
||||
// exec/eval
|
||||
Frame(PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable, FastLocals _locals)
|
||||
Frame(PyVar* p0, const CodeObject* co, PyVar _module, PyVar _callable, FastLocals _locals)
|
||||
: _ip(-1), _next_ip(0), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(_locals) { }
|
||||
|
||||
// global scope
|
||||
Frame(PyObject** p0, const CodeObject_& co, PyObject* _module)
|
||||
Frame(PyVar* p0, const CodeObject_& co, PyVar _module)
|
||||
: _ip(-1), _next_ip(0), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _locals(co.get(), p0) {}
|
||||
|
||||
int next_bytecode() {
|
||||
@ -100,7 +100,7 @@ struct Frame {
|
||||
return _ip;
|
||||
}
|
||||
|
||||
PyObject** actual_sp_base() const { return _locals.a; }
|
||||
PyVar* actual_sp_base() const { return _locals.a; }
|
||||
|
||||
int stack_size(ValueStack* _s) const { return _s->_sp - actual_sp_base(); }
|
||||
ArgsView stack_view(ValueStack* _s) const { return ArgsView(actual_sp_base(), _s->_sp); }
|
||||
|
@ -8,10 +8,10 @@
|
||||
|
||||
namespace pkpy {
|
||||
struct ManagedHeap{
|
||||
std::vector<PyObject*> _no_gc;
|
||||
std::vector<PyObject*> gen;
|
||||
std::vector<PyVar> _no_gc;
|
||||
std::vector<PyVar> gen;
|
||||
VM* vm;
|
||||
void (*_gc_on_delete)(VM*, PyObject*) = nullptr;
|
||||
void (*_gc_on_delete)(VM*, PyVar) = nullptr;
|
||||
void (*_gc_marker_ex)(VM*) = nullptr;
|
||||
|
||||
ManagedHeap(VM* vm): vm(vm) {}
|
||||
@ -39,20 +39,20 @@ struct ManagedHeap{
|
||||
/********************/
|
||||
|
||||
template<typename T, typename... Args>
|
||||
PyObject* gcnew(Type type, Args&&... args){
|
||||
PyVar gcnew(Type type, Args&&... args){
|
||||
using __T = Py_<std::decay_t<T>>;
|
||||
// https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
|
||||
PyObject* obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
|
||||
PyVar obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
|
||||
gen.push_back(obj);
|
||||
gc_counter++;
|
||||
return obj;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
PyObject* _new(Type type, Args&&... args){
|
||||
PyVar _new(Type type, Args&&... args){
|
||||
using __T = Py_<std::decay_t<T>>;
|
||||
// https://github.com/pocketpy/pocketpy/issues/94#issuecomment-1594784476
|
||||
PyObject* obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
|
||||
PyVar obj = new(pool64_alloc<__T>()) Py_<std::decay_t<T>>(type, std::forward<Args>(args)...);
|
||||
obj->gc_enabled = false;
|
||||
_no_gc.push_back(obj);
|
||||
return obj;
|
||||
|
@ -11,28 +11,28 @@ struct RangeIter{
|
||||
i64 current;
|
||||
RangeIter(Range r) : r(r), current(r.start) {}
|
||||
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
};
|
||||
|
||||
struct ArrayIter{
|
||||
PyObject* ref;
|
||||
PyObject** begin;
|
||||
PyObject** end;
|
||||
PyObject** current;
|
||||
PyVar ref;
|
||||
PyVar* begin;
|
||||
PyVar* end;
|
||||
PyVar* current;
|
||||
|
||||
ArrayIter(PyObject* ref, PyObject** begin, PyObject** end)
|
||||
ArrayIter(PyVar ref, PyVar* begin, PyVar* end)
|
||||
: ref(ref), begin(begin), end(end), current(begin) {}
|
||||
|
||||
void _gc_mark() const{ PK_OBJ_MARK(ref); }
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
};
|
||||
|
||||
struct StringIter{
|
||||
PyObject* ref;
|
||||
PyVar ref;
|
||||
int i; // byte index
|
||||
StringIter(PyObject* ref) : ref(ref), i(0) {}
|
||||
StringIter(PyVar ref) : ref(ref), i(0) {}
|
||||
void _gc_mark() const{ PK_OBJ_MARK(ref); }
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
};
|
||||
|
||||
struct Generator{
|
||||
@ -41,26 +41,26 @@ struct Generator{
|
||||
List s_backup;
|
||||
|
||||
Generator(Frame&& frame, ArgsView buffer): frame(std::move(frame)), state(0) {
|
||||
for(PyObject* obj: buffer) s_backup.push_back(obj);
|
||||
for(PyVar obj: buffer) s_backup.push_back(obj);
|
||||
}
|
||||
|
||||
void _gc_mark() const{
|
||||
frame._gc_mark();
|
||||
for(PyObject* obj: s_backup) PK_OBJ_MARK(obj);
|
||||
for(PyVar obj: s_backup) PK_OBJ_MARK(obj);
|
||||
}
|
||||
|
||||
PyObject* next(VM* vm);
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
PyVar next(VM* vm);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
};
|
||||
|
||||
struct DictItemsIter{
|
||||
PyObject* ref;
|
||||
PyVar ref;
|
||||
int i;
|
||||
DictItemsIter(PyObject* ref) : ref(ref) {
|
||||
DictItemsIter(PyVar ref) : ref(ref) {
|
||||
i = PK_OBJ_GET(Dict, ref)._head_idx;
|
||||
}
|
||||
void _gc_mark() const{ PK_OBJ_MARK(ref); }
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
};
|
||||
|
||||
} // namespace pkpy
|
@ -7,7 +7,7 @@ namespace pkpy{
|
||||
inline bool isclose(float a, float b){ return std::fabs(a - b) < 1e-4; }
|
||||
|
||||
struct Vec2{
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
|
||||
float x, y;
|
||||
Vec2() : x(0.0f), y(0.0f) {}
|
||||
@ -32,7 +32,7 @@ struct Vec2{
|
||||
};
|
||||
|
||||
struct Vec3{
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
|
||||
float x, y, z;
|
||||
Vec3() : x(0.0f), y(0.0f), z(0.0f) {}
|
||||
@ -56,7 +56,7 @@ struct Vec3{
|
||||
};
|
||||
|
||||
struct Vec4{
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
|
||||
float x, y, z, w;
|
||||
Vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) {}
|
||||
@ -79,7 +79,7 @@ struct Vec4{
|
||||
};
|
||||
|
||||
struct Mat3x3{
|
||||
static void _register(VM* vm, PyObject* mod, PyObject* type);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
|
||||
union {
|
||||
struct {
|
||||
|
@ -334,7 +334,7 @@ struct NameDictImpl{
|
||||
}
|
||||
};
|
||||
|
||||
using NameDict = NameDictImpl<PyObject*>;
|
||||
using NameDict = NameDictImpl<PyVar>;
|
||||
using NameDict_ = std::shared_ptr<NameDict>;
|
||||
using NameDictInt = NameDictImpl<int>;
|
||||
|
||||
|
@ -10,9 +10,9 @@ struct Frame;
|
||||
class VM;
|
||||
|
||||
#if PK_ENABLE_STD_FUNCTION
|
||||
using NativeFuncC = std::function<PyObject*(VM*, ArgsView)>;
|
||||
using NativeFuncC = std::function<PyVar(VM*, ArgsView)>;
|
||||
#else
|
||||
typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
|
||||
typedef PyVar (*NativeFuncC)(VM*, ArgsView);
|
||||
#endif
|
||||
|
||||
enum class BindType{
|
||||
@ -22,25 +22,25 @@ enum class BindType{
|
||||
};
|
||||
|
||||
struct BoundMethod {
|
||||
PyObject* self;
|
||||
PyObject* func;
|
||||
BoundMethod(PyObject* self, PyObject* func) : self(self), func(func) {}
|
||||
PyVar self;
|
||||
PyVar func;
|
||||
BoundMethod(PyVar self, PyVar func) : self(self), func(func) {}
|
||||
};
|
||||
|
||||
struct StaticMethod{
|
||||
PyObject* func;
|
||||
StaticMethod(PyObject* func) : func(func) {}
|
||||
PyVar func;
|
||||
StaticMethod(PyVar func) : func(func) {}
|
||||
};
|
||||
|
||||
struct ClassMethod{
|
||||
PyObject* func;
|
||||
ClassMethod(PyObject* func) : func(func) {}
|
||||
PyVar func;
|
||||
ClassMethod(PyVar func) : func(func) {}
|
||||
};
|
||||
|
||||
struct Property{
|
||||
PyObject* getter;
|
||||
PyObject* setter;
|
||||
Property(PyObject* getter, PyObject* setter) : getter(getter), setter(setter) {}
|
||||
PyVar getter;
|
||||
PyVar setter;
|
||||
Property(PyVar getter, PyVar setter) : getter(getter), setter(setter) {}
|
||||
};
|
||||
|
||||
struct Range {
|
||||
@ -51,8 +51,8 @@ struct Range {
|
||||
|
||||
struct StarWrapper{
|
||||
int level; // either 1 or 2
|
||||
PyObject* obj;
|
||||
StarWrapper(int level, PyObject* obj) : level(level), obj(obj) {}
|
||||
PyVar obj;
|
||||
StarWrapper(int level, PyVar obj) : level(level), obj(obj) {}
|
||||
};
|
||||
|
||||
struct Bytes{
|
||||
@ -84,13 +84,13 @@ struct Bytes{
|
||||
~Bytes(){ delete[] _data;}
|
||||
};
|
||||
|
||||
using Super = std::pair<PyObject*, Type>;
|
||||
using Super = std::pair<PyVar, Type>;
|
||||
|
||||
struct Slice {
|
||||
PyObject* start;
|
||||
PyObject* stop;
|
||||
PyObject* step;
|
||||
Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {}
|
||||
PyVar start;
|
||||
PyVar stop;
|
||||
PyVar step;
|
||||
Slice(PyVar start, PyVar stop, PyVar step) : start(start), stop(stop), step(step) {}
|
||||
};
|
||||
|
||||
struct PyObject{
|
||||
@ -106,7 +106,7 @@ struct PyObject{
|
||||
return *_attr;
|
||||
}
|
||||
|
||||
PyObject* attr(StrName name) const {
|
||||
PyVar attr(StrName name) const {
|
||||
PK_DEBUG_ASSERT(is_attr_valid())
|
||||
return (*_attr)[name];
|
||||
}
|
||||
@ -128,13 +128,13 @@ struct PyObject{
|
||||
const int kTpIntIndex = 2;
|
||||
const int kTpFloatIndex = 3;
|
||||
|
||||
inline bool is_tagged(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) != 0b00; }
|
||||
inline bool is_small_int(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) == 0b10; }
|
||||
inline bool is_heap_int(PyObject* p) noexcept { return !is_tagged(p) && p->type.index == kTpIntIndex; }
|
||||
inline bool is_float(PyObject* p) noexcept { return !is_tagged(p) && p->type.index == kTpFloatIndex; }
|
||||
inline bool is_int(PyObject* p) noexcept { return is_small_int(p) || is_heap_int(p); }
|
||||
inline bool is_tagged(PyVar p) noexcept { return (PK_BITS(p) & 0b11) != 0b00; }
|
||||
inline bool is_small_int(PyVar p) noexcept { return (PK_BITS(p) & 0b11) == 0b10; }
|
||||
inline bool is_heap_int(PyVar p) noexcept { return !is_tagged(p) && p->type.index == kTpIntIndex; }
|
||||
inline bool is_float(PyVar p) noexcept { return !is_tagged(p) && p->type.index == kTpFloatIndex; }
|
||||
inline bool is_int(PyVar p) noexcept { return is_small_int(p) || is_heap_int(p); }
|
||||
|
||||
inline bool is_type(PyObject* obj, Type type) {
|
||||
inline bool is_type(PyVar obj, Type type) {
|
||||
PK_DEBUG_ASSERT(obj != nullptr)
|
||||
return is_small_int(obj) ? type.index == kTpIntIndex : obj->type == type;
|
||||
}
|
||||
@ -158,15 +158,15 @@ struct Py_ final: PyObject {
|
||||
};
|
||||
|
||||
struct MappingProxy{
|
||||
PyObject* obj;
|
||||
MappingProxy(PyObject* obj) : obj(obj) {}
|
||||
PyVar obj;
|
||||
MappingProxy(PyVar obj) : obj(obj) {}
|
||||
NameDict& attr() { return obj->attr(); }
|
||||
};
|
||||
|
||||
void _gc_mark_namedict(NameDict*);
|
||||
StrName _type_name(VM* vm, Type type);
|
||||
template<typename T> T to_void_p(VM*, PyObject*);
|
||||
PyObject* from_void_p(VM*, void*);
|
||||
template<typename T> T to_void_p(VM*, PyVar);
|
||||
PyVar from_void_p(VM*, void*);
|
||||
|
||||
|
||||
#define PK_OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
|
||||
@ -193,7 +193,7 @@ struct Py_<i64> final: PyObject {
|
||||
void _obj_gc_mark() override {}
|
||||
};
|
||||
|
||||
inline bool try_cast_int(PyObject* obj, i64* val) noexcept {
|
||||
inline bool try_cast_int(PyVar obj, i64* val) noexcept {
|
||||
if(is_small_int(obj)){
|
||||
*val = PK_BITS(obj) >> 2;
|
||||
return true;
|
||||
@ -212,7 +212,7 @@ struct Py_<List> final: PyObject {
|
||||
Py_(Type type, const List& val): PyObject(type), _value(val) {}
|
||||
|
||||
void _obj_gc_mark() override {
|
||||
for(PyObject* obj: _value) PK_OBJ_MARK(obj);
|
||||
for(PyVar obj: _value) PK_OBJ_MARK(obj);
|
||||
}
|
||||
};
|
||||
|
||||
@ -223,7 +223,7 @@ struct Py_<Tuple> final: PyObject {
|
||||
Py_(Type type, const Tuple& val): PyObject(type), _value(val) {}
|
||||
|
||||
void _obj_gc_mark() override {
|
||||
for(PyObject* obj: _value) PK_OBJ_MARK(obj);
|
||||
for(PyVar obj: _value) PK_OBJ_MARK(obj);
|
||||
}
|
||||
};
|
||||
|
||||
@ -329,8 +329,8 @@ struct Py_<DummyModule> final: PyObject {
|
||||
void _obj_gc_mark() override {}
|
||||
};
|
||||
|
||||
extern PyObject* const PY_NULL;
|
||||
extern PyObject* const PY_OP_CALL;
|
||||
extern PyObject* const PY_OP_YIELD;
|
||||
extern PyVar const PY_NULL;
|
||||
extern PyVar const PY_OP_CALL;
|
||||
extern PyVar const PY_OP_YIELD;
|
||||
|
||||
} // namespace pkpy
|
@ -7,11 +7,11 @@
|
||||
|
||||
namespace pkpy {
|
||||
|
||||
using List = pod_vector<PyObject*, 4>;
|
||||
using List = pod_vector<PyVar, 4>;
|
||||
|
||||
struct Tuple {
|
||||
PyObject** _args;
|
||||
PyObject* _inlined[3];
|
||||
PyVar* _args;
|
||||
PyVar _inlined[3];
|
||||
int _size;
|
||||
|
||||
Tuple(int n);
|
||||
@ -20,34 +20,34 @@ struct Tuple {
|
||||
Tuple(List&& other) noexcept;
|
||||
~Tuple();
|
||||
|
||||
Tuple(PyObject*, PyObject*);
|
||||
Tuple(PyObject*, PyObject*, PyObject*);
|
||||
Tuple(PyObject*, PyObject*, PyObject*, PyObject*);
|
||||
Tuple(PyVar, PyVar);
|
||||
Tuple(PyVar, PyVar, PyVar);
|
||||
Tuple(PyVar, PyVar, PyVar, PyVar);
|
||||
|
||||
bool is_inlined() const { return _args == _inlined; }
|
||||
PyObject*& operator[](int i){ return _args[i]; }
|
||||
PyObject* operator[](int i) const { return _args[i]; }
|
||||
PyVar& operator[](int i){ return _args[i]; }
|
||||
PyVar operator[](int i) const { return _args[i]; }
|
||||
|
||||
int size() const { return _size; }
|
||||
|
||||
PyObject** begin() const { return _args; }
|
||||
PyObject** end() const { return _args + _size; }
|
||||
PyObject** data() const { return _args; }
|
||||
PyVar* begin() const { return _args; }
|
||||
PyVar* end() const { return _args + _size; }
|
||||
PyVar* data() const { return _args; }
|
||||
};
|
||||
|
||||
// a lightweight view for function args, it does not own the memory
|
||||
struct ArgsView{
|
||||
PyObject** _begin;
|
||||
PyObject** _end;
|
||||
PyVar* _begin;
|
||||
PyVar* _end;
|
||||
|
||||
ArgsView(PyObject** begin, PyObject** end) : _begin(begin), _end(end) {}
|
||||
ArgsView(PyVar* begin, PyVar* end) : _begin(begin), _end(end) {}
|
||||
ArgsView(const Tuple& t) : _begin(t.begin()), _end(t.end()) {}
|
||||
|
||||
PyObject** begin() const { return _begin; }
|
||||
PyObject** end() const { return _end; }
|
||||
PyVar* begin() const { return _begin; }
|
||||
PyVar* end() const { return _end; }
|
||||
int size() const { return _end - _begin; }
|
||||
bool empty() const { return _begin == _end; }
|
||||
PyObject* operator[](int i) const { return _begin[i]; }
|
||||
PyVar operator[](int i) const { return _begin[i]; }
|
||||
|
||||
List to_list() const;
|
||||
Tuple to_tuple() const;
|
||||
|
@ -26,8 +26,8 @@ namespace pkpy{
|
||||
#define POPX() (s_data.popx())
|
||||
#define STACK_VIEW(n) (s_data.view(n))
|
||||
|
||||
typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
|
||||
typedef void (*RegisterFunc)(VM*, PyObject*, PyObject*);
|
||||
typedef PyVar (*BinaryFuncC)(VM*, PyVar, PyVar);
|
||||
typedef void (*RegisterFunc)(VM*, PyVar, PyVar);
|
||||
|
||||
#if PK_ENABLE_PROFILER
|
||||
struct NextBreakpoint{
|
||||
@ -42,23 +42,23 @@ struct NextBreakpoint{
|
||||
#endif
|
||||
|
||||
struct PyTypeInfo{
|
||||
PyObject* obj; // never be garbage collected
|
||||
PyVar obj; // never be garbage collected
|
||||
Type base;
|
||||
PyObject* mod; // never be garbage collected
|
||||
PyVar mod; // never be garbage collected
|
||||
StrName name;
|
||||
bool subclass_enabled;
|
||||
|
||||
std::vector<StrName> annotated_fields = {};
|
||||
|
||||
// unary operators
|
||||
Str (*m__repr__)(VM* vm, PyObject*) = nullptr;
|
||||
Str (*m__str__)(VM* vm, PyObject*) = nullptr;
|
||||
i64 (*m__hash__)(VM* vm, PyObject*) = nullptr;
|
||||
i64 (*m__len__)(VM* vm, PyObject*) = nullptr;
|
||||
PyObject* (*m__iter__)(VM* vm, PyObject*) = nullptr;
|
||||
unsigned (*m__next__)(VM* vm, PyObject*) = nullptr;
|
||||
PyObject* (*m__neg__)(VM* vm, PyObject*) = nullptr;
|
||||
PyObject* (*m__invert__)(VM* vm, PyObject*) = nullptr;
|
||||
Str (*m__repr__)(VM* vm, PyVar) = nullptr;
|
||||
Str (*m__str__)(VM* vm, PyVar) = nullptr;
|
||||
i64 (*m__hash__)(VM* vm, PyVar) = nullptr;
|
||||
i64 (*m__len__)(VM* vm, PyVar) = nullptr;
|
||||
PyVar (*m__iter__)(VM* vm, PyVar) = nullptr;
|
||||
unsigned (*m__next__)(VM* vm, PyVar) = nullptr;
|
||||
PyVar (*m__neg__)(VM* vm, PyVar) = nullptr;
|
||||
PyVar (*m__invert__)(VM* vm, PyVar) = nullptr;
|
||||
|
||||
BinaryFuncC m__eq__ = nullptr;
|
||||
BinaryFuncC m__lt__ = nullptr;
|
||||
@ -84,14 +84,14 @@ struct PyTypeInfo{
|
||||
BinaryFuncC m__xor__ = nullptr;
|
||||
|
||||
// indexer
|
||||
PyObject* (*m__getitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
|
||||
void (*m__setitem__)(VM* vm, PyObject*, PyObject*, PyObject*) = nullptr;
|
||||
void (*m__delitem__)(VM* vm, PyObject*, PyObject*) = nullptr;
|
||||
PyVar (*m__getitem__)(VM* vm, PyVar, PyVar) = nullptr;
|
||||
void (*m__setitem__)(VM* vm, PyVar, PyVar, PyVar) = nullptr;
|
||||
void (*m__delitem__)(VM* vm, PyVar, PyVar) = nullptr;
|
||||
|
||||
// attributes
|
||||
void (*m__setattr__)(VM* vm, PyObject*, StrName, PyObject*) = nullptr;
|
||||
PyObject* (*m__getattr__)(VM* vm, PyObject*, StrName) = nullptr;
|
||||
bool (*m__delattr__)(VM* vm, PyObject*, StrName) = nullptr;
|
||||
void (*m__setattr__)(VM* vm, PyVar, StrName, PyVar) = nullptr;
|
||||
PyVar (*m__getattr__)(VM* vm, PyVar, StrName) = nullptr;
|
||||
bool (*m__delattr__)(VM* vm, PyVar, StrName) = nullptr;
|
||||
|
||||
// backdoors
|
||||
void (*on_end_subclass)(VM* vm, PyTypeInfo*) = nullptr;
|
||||
@ -138,25 +138,25 @@ public:
|
||||
std::map<StrName, Str> _lazy_modules; // lazy loaded modules
|
||||
|
||||
struct{
|
||||
PyObject* error;
|
||||
PyVar error;
|
||||
stack_no_copy<ArgsView> s_view;
|
||||
} __c;
|
||||
|
||||
PyObject *None, *True, *False, *NotImplemented;
|
||||
PyObject *StopIteration, *Ellipsis;
|
||||
PyObject *builtins, *_main;
|
||||
PyVar None, True, False, NotImplemented;
|
||||
PyVar StopIteration, Ellipsis;
|
||||
PyVar builtins, _main;
|
||||
|
||||
// typeid -> Type
|
||||
std::map<const std::type_index, Type> _cxx_typeid_map;
|
||||
// this is for repr() recursion detection (no need to mark)
|
||||
std::set<PyObject*> _repr_recursion_set;
|
||||
std::set<PyVar> _repr_recursion_set;
|
||||
|
||||
ImportContext __import_context;
|
||||
PyObject* __last_exception;
|
||||
PyObject* __curr_class;
|
||||
PyObject* __cached_object_new;
|
||||
PyVar __last_exception;
|
||||
PyVar __curr_class;
|
||||
PyVar __cached_object_new;
|
||||
std::map<std::string_view, CodeObject_> __cached_codes;
|
||||
std::map<std::string_view, PyObject*> __cached_op_funcs;
|
||||
std::map<std::string_view, PyVar> __cached_op_funcs;
|
||||
FuncDecl_ __dynamic_func_decl;
|
||||
|
||||
#if PK_ENABLE_PROFILER
|
||||
@ -186,38 +186,38 @@ public:
|
||||
VM(bool enable_os=true);
|
||||
|
||||
#if PK_REGION("Python Equivalents")
|
||||
Str py_str(PyObject* obj); // x -> str(x)
|
||||
Str py_repr(PyObject* obj); // x -> repr(x)
|
||||
Str py_json(PyObject* obj); // x -> json.dumps(x)
|
||||
Str py_str(PyVar obj); // x -> str(x)
|
||||
Str py_repr(PyVar obj); // x -> repr(x)
|
||||
Str py_json(PyVar obj); // x -> json.dumps(x)
|
||||
|
||||
PyObject* py_iter(PyObject* obj); // x -> iter(x)
|
||||
PyObject* py_next(PyObject*); // x -> next(x)
|
||||
PyObject* _py_next(const PyTypeInfo*, PyObject*); // x -> next(x) with type info cache
|
||||
PyObject* py_import(Str path, bool throw_err=true); // x -> __import__(x)
|
||||
PyObject* py_negate(PyObject* obj); // x -> -x
|
||||
PyVar py_iter(PyVar obj); // x -> iter(x)
|
||||
PyVar py_next(PyVar); // x -> next(x)
|
||||
PyVar _py_next(const PyTypeInfo*, PyVar); // x -> next(x) with type info cache
|
||||
PyVar py_import(Str path, bool throw_err=true); // x -> __import__(x)
|
||||
PyVar py_negate(PyVar obj); // x -> -x
|
||||
|
||||
List py_list(PyObject*); // x -> list(x)
|
||||
bool py_callable(PyObject* obj); // x -> callable(x)
|
||||
bool py_bool(PyObject* obj); // x -> bool(x)
|
||||
i64 py_hash(PyObject* obj); // x -> hash(x)
|
||||
List py_list(PyVar); // x -> list(x)
|
||||
bool py_callable(PyVar obj); // x -> callable(x)
|
||||
bool py_bool(PyVar obj); // x -> bool(x)
|
||||
i64 py_hash(PyVar obj); // x -> hash(x)
|
||||
|
||||
bool py_eq(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs == rhs
|
||||
bool py_lt(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs < rhs
|
||||
bool py_le(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs <= rhs
|
||||
bool py_gt(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs > rhs
|
||||
bool py_ge(PyObject* lhs, PyObject* rhs); // (lhs, rhs) -> lhs >= rhs
|
||||
bool py_ne(PyObject* lhs, PyObject* rhs){ // (lhs, rhs) -> lhs != rhs
|
||||
bool py_eq(PyVar lhs, PyVar rhs); // (lhs, rhs) -> lhs == rhs
|
||||
bool py_lt(PyVar lhs, PyVar rhs); // (lhs, rhs) -> lhs < rhs
|
||||
bool py_le(PyVar lhs, PyVar rhs); // (lhs, rhs) -> lhs <= rhs
|
||||
bool py_gt(PyVar lhs, PyVar rhs); // (lhs, rhs) -> lhs > rhs
|
||||
bool py_ge(PyVar lhs, PyVar rhs); // (lhs, rhs) -> lhs >= rhs
|
||||
bool py_ne(PyVar lhs, PyVar rhs){ // (lhs, rhs) -> lhs != rhs
|
||||
return !py_eq(lhs, rhs);
|
||||
}
|
||||
|
||||
PyObject* py_op(std::string_view name); // (name) -> operator.name
|
||||
PyVar py_op(std::string_view name); // (name) -> operator.name
|
||||
|
||||
void py_exec(std::string_view, PyObject*, PyObject*); // exec(source, globals, locals)
|
||||
PyObject* py_eval(std::string_view, PyObject*, PyObject*); // eval(source, globals, locals)
|
||||
void py_exec(std::string_view, PyVar, PyVar); // exec(source, globals, locals)
|
||||
PyVar py_eval(std::string_view, PyVar, PyVar); // eval(source, globals, locals)
|
||||
#endif
|
||||
|
||||
#if PK_REGION("Utility Methods")
|
||||
ArgsView cast_array_view(PyObject* obj);
|
||||
ArgsView cast_array_view(PyVar obj);
|
||||
void set_main_argv(int argc, char** argv);
|
||||
i64 normalized_index(i64 index, int size);
|
||||
Str disassemble(CodeObject_ co);
|
||||
@ -225,47 +225,47 @@ public:
|
||||
#endif
|
||||
|
||||
#if PK_REGION("Name Lookup Methods")
|
||||
PyObject* find_name_in_mro(Type cls, StrName name);
|
||||
PyObject* get_unbound_method(PyObject* obj, StrName name, PyObject** self, bool throw_err=true, bool fallback=false);
|
||||
PyObject* getattr(PyObject* obj, StrName name, bool throw_err=true);
|
||||
void delattr(PyObject* obj, StrName name);
|
||||
void setattr(PyObject* obj, StrName name, PyObject* value);
|
||||
PyVar find_name_in_mro(Type cls, StrName name);
|
||||
PyVar get_unbound_method(PyVar obj, StrName name, PyVar* self, bool throw_err=true, bool fallback=false);
|
||||
PyVar getattr(PyVar obj, StrName name, bool throw_err=true);
|
||||
void delattr(PyVar obj, StrName name);
|
||||
void setattr(PyVar obj, StrName name, PyVar value);
|
||||
#endif
|
||||
|
||||
#if PK_REGION("Source Execution Methods")
|
||||
CodeObject_ compile(std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
|
||||
Str precompile(std::string_view source, const Str& filename, CompileMode mode);
|
||||
PyObject* exec(std::string_view source, Str filename, CompileMode mode, PyObject* _module=nullptr);
|
||||
PyObject* exec(std::string_view source);
|
||||
PyObject* eval(std::string_view source);
|
||||
PyVar exec(std::string_view source, Str filename, CompileMode mode, PyVar _module=nullptr);
|
||||
PyVar exec(std::string_view source);
|
||||
PyVar eval(std::string_view source);
|
||||
|
||||
template<typename ...Args>
|
||||
PyObject* _exec(Args&&... args){
|
||||
PyVar _exec(Args&&... args){
|
||||
callstack.emplace(s_data._sp, std::forward<Args>(args)...);
|
||||
return __run_top_frame();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if PK_REGION("Invocation Methods")
|
||||
PyObject* vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
|
||||
PyVar vectorcall(int ARGC, int KWARGC=0, bool op_call=false);
|
||||
|
||||
template<typename... Args>
|
||||
PyObject* call(PyObject* callable, Args&&... args){
|
||||
PyVar call(PyVar callable, Args&&... args){
|
||||
PUSH(callable); PUSH(PY_NULL);
|
||||
__push_varargs(args...);
|
||||
return vectorcall(sizeof...(args));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
PyObject* call_method(PyObject* self, PyObject* callable, Args&&... args){
|
||||
PyVar call_method(PyVar self, PyVar callable, Args&&... args){
|
||||
PUSH(callable); PUSH(self);
|
||||
__push_varargs(args...);
|
||||
return vectorcall(sizeof...(args));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
PyObject* call_method(PyObject* self, StrName name, Args&&... args){
|
||||
PyObject* callable = get_unbound_method(self, name, &self);
|
||||
PyVar call_method(PyVar self, StrName name, Args&&... args){
|
||||
PyVar callable = get_unbound_method(self, name, &self);
|
||||
return call_method(self, callable, args...);
|
||||
}
|
||||
#endif
|
||||
@ -276,16 +276,16 @@ public:
|
||||
#endif
|
||||
|
||||
#if PK_REGION("Magic Bindings")
|
||||
void bind__repr__(Type type, Str (*f)(VM*, PyObject*));
|
||||
void bind__str__(Type type, Str (*f)(VM*, PyObject*));
|
||||
void bind__iter__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__repr__(Type type, Str (*f)(VM*, PyVar));
|
||||
void bind__str__(Type type, Str (*f)(VM*, PyVar));
|
||||
void bind__iter__(Type type, PyVar (*f)(VM*, PyVar));
|
||||
|
||||
void bind__next__(Type type, unsigned (*f)(VM*, PyObject*));
|
||||
[[deprecated]] void bind__next__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__neg__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__invert__(Type type, PyObject* (*f)(VM*, PyObject*));
|
||||
void bind__hash__(Type type, i64 (*f)(VM* vm, PyObject*));
|
||||
void bind__len__(Type type, i64 (*f)(VM* vm, PyObject*));
|
||||
void bind__next__(Type type, unsigned (*f)(VM*, PyVar));
|
||||
[[deprecated]] void bind__next__(Type type, PyVar (*f)(VM*, PyVar));
|
||||
void bind__neg__(Type type, PyVar (*f)(VM*, PyVar));
|
||||
void bind__invert__(Type type, PyVar (*f)(VM*, PyVar));
|
||||
void bind__hash__(Type type, i64 (*f)(VM* vm, PyVar));
|
||||
void bind__len__(Type type, i64 (*f)(VM* vm, PyVar));
|
||||
|
||||
void bind__eq__(Type type, BinaryFuncC f);
|
||||
void bind__lt__(Type type, BinaryFuncC f);
|
||||
@ -309,35 +309,35 @@ public:
|
||||
void bind__or__(Type type, BinaryFuncC f);
|
||||
void bind__xor__(Type type, BinaryFuncC f);
|
||||
|
||||
void bind__getitem__(Type type, PyObject* (*f)(VM*, PyObject*, PyObject*));
|
||||
void bind__setitem__(Type type, void (*f)(VM*, PyObject*, PyObject*, PyObject*));
|
||||
void bind__delitem__(Type type, void (*f)(VM*, PyObject*, PyObject*));
|
||||
void bind__getitem__(Type type, PyVar (*f)(VM*, PyVar, PyVar));
|
||||
void bind__setitem__(Type type, void (*f)(VM*, PyVar, PyVar, PyVar));
|
||||
void bind__delitem__(Type type, void (*f)(VM*, PyVar, PyVar));
|
||||
#endif
|
||||
|
||||
#if PK_REGION("General Bindings")
|
||||
PyObject* bind_func(PyObject* obj, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT);
|
||||
PyObject* bind_func(Type type, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT){
|
||||
PyVar bind_func(PyVar obj, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT);
|
||||
PyVar bind_func(Type type, StrName name, int argc, NativeFuncC fn, any userdata={}, BindType bt=BindType::DEFAULT){
|
||||
return bind_func(_t(type), name, argc, fn, std::move(userdata), bt);
|
||||
}
|
||||
PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
|
||||
PyVar bind_property(PyVar, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
|
||||
template<typename T, typename F, bool ReadOnly=false>
|
||||
PyObject* bind_field(PyObject*, const char*, F T::*);
|
||||
PyVar bind_field(PyVar, const char*, F T::*);
|
||||
|
||||
PyObject* bind(PyObject*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
|
||||
PyVar bind(PyVar, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
|
||||
template<typename Ret, typename... Params>
|
||||
PyObject* bind(PyObject*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
PyVar bind(PyVar, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
template<typename Ret, typename T, typename... Params>
|
||||
PyObject* bind(PyObject*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
PyVar bind(PyVar, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
|
||||
PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
|
||||
PyVar bind(PyVar, const char*, const char*, NativeFuncC, any userdata={}, BindType bt=BindType::DEFAULT);
|
||||
template<typename Ret, typename... Params>
|
||||
PyObject* bind(PyObject*, const char*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
PyVar bind(PyVar, const char*, const char*, Ret(*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
template<typename Ret, typename T, typename... Params>
|
||||
PyObject* bind(PyObject*, const char*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
PyVar bind(PyVar, const char*, const char*, Ret(T::*)(Params...), BindType bt=BindType::DEFAULT);
|
||||
#endif
|
||||
|
||||
#if PK_REGION("Error Reporting Methods")
|
||||
void _error(PyObject*);
|
||||
void _error(PyVar);
|
||||
void StackOverflowError() { __builtin_error("StackOverflowError"); }
|
||||
void IOError(const Str& msg) { __builtin_error("IOError", msg); }
|
||||
void NotImplementedError(){ __builtin_error("NotImplementedError"); }
|
||||
@ -350,44 +350,44 @@ public:
|
||||
void ZeroDivisionError(){ __builtin_error("ZeroDivisionError", "division by zero"); }
|
||||
void NameError(StrName name){ __builtin_error("NameError", _S("name ", name.escape() + " is not defined")); }
|
||||
void UnboundLocalError(StrName name){ __builtin_error("UnboundLocalError", _S("local variable ", name.escape() + " referenced before assignment")); }
|
||||
void KeyError(PyObject* obj){ __builtin_error("KeyError", obj); }
|
||||
void KeyError(PyVar obj){ __builtin_error("KeyError", obj); }
|
||||
void ImportError(const Str& msg){ __builtin_error("ImportError", msg); }
|
||||
void AssertionError(const Str& msg){ __builtin_error("AssertionError", msg); }
|
||||
void AssertionError(){ __builtin_error("AssertionError"); }
|
||||
void BinaryOptError(const char* op, PyObject* _0, PyObject* _1);
|
||||
void AttributeError(PyObject* obj, StrName name);
|
||||
void BinaryOptError(const char* op, PyVar _0, PyVar _1);
|
||||
void AttributeError(PyVar obj, StrName name);
|
||||
void AttributeError(const Str& msg){ __builtin_error("AttributeError", msg); }
|
||||
#endif
|
||||
|
||||
#if PK_REGION("Type Checking Methods")
|
||||
bool isinstance(PyObject* obj, Type base);
|
||||
bool isinstance(PyVar obj, Type base);
|
||||
bool issubclass(Type cls, Type base);
|
||||
void check_type(PyObject* obj, Type type){ if(!is_type(obj, type)) TypeError(type, _tp(obj)); }
|
||||
void check_compatible_type(PyObject* obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); }
|
||||
void check_type(PyVar obj, Type type){ if(!is_type(obj, type)) TypeError(type, _tp(obj)); }
|
||||
void check_compatible_type(PyVar obj, Type type){ if(!isinstance(obj, type)) TypeError(type, _tp(obj)); }
|
||||
|
||||
Type _tp(PyObject* obj){ return is_small_int(obj) ? tp_int : obj->type; }
|
||||
const PyTypeInfo* _tp_info(PyObject* obj) { return &_all_types[_tp(obj)]; }
|
||||
Type _tp(PyVar obj){ return is_small_int(obj) ? tp_int : obj->type; }
|
||||
const PyTypeInfo* _tp_info(PyVar obj) { return &_all_types[_tp(obj)]; }
|
||||
const PyTypeInfo* _tp_info(Type type) { return &_all_types[type]; }
|
||||
PyObject* _t(PyObject* obj){ return _all_types[_tp(obj)].obj; }
|
||||
PyObject* _t(Type type){ return _all_types[type].obj; }
|
||||
PyVar _t(PyVar obj){ return _all_types[_tp(obj)].obj; }
|
||||
PyVar _t(Type type){ return _all_types[type].obj; }
|
||||
#endif
|
||||
|
||||
#if PK_REGION("User Type Registration")
|
||||
PyObject* new_module(Str name, Str package="");
|
||||
PyObject* new_type_object(PyObject* mod, StrName name, Type base, bool subclass_enabled=true);
|
||||
PyVar new_module(Str name, Str package="");
|
||||
PyVar new_type_object(PyVar mod, StrName name, Type base, bool subclass_enabled=true);
|
||||
|
||||
template<typename T>
|
||||
Type _tp_user(){ return _find_type_in_cxx_typeid_map<T>(); }
|
||||
template<typename T>
|
||||
bool is_user_type(PyObject* obj){ return _tp(obj) == _tp_user<T>(); }
|
||||
bool is_user_type(PyVar obj){ return _tp(obj) == _tp_user<T>(); }
|
||||
|
||||
template<typename T>
|
||||
PyObject* register_user_class(PyObject*, StrName, RegisterFunc, Type base=tp_object, bool subclass_enabled=false);
|
||||
PyVar register_user_class(PyVar, StrName, RegisterFunc, Type base=tp_object, bool subclass_enabled=false);
|
||||
template<typename T>
|
||||
PyObject* register_user_class(PyObject*, StrName, Type base=tp_object, bool subclass_enabled=false);
|
||||
PyVar register_user_class(PyVar, StrName, Type base=tp_object, bool subclass_enabled=false);
|
||||
|
||||
template<typename T, typename ...Args>
|
||||
PyObject* new_user_object(Args&&... args){
|
||||
PyVar new_user_object(Args&&... args){
|
||||
return heap.gcnew<T>(_tp_user<T>(), std::forward<Args>(args)...);
|
||||
}
|
||||
#endif
|
||||
@ -413,29 +413,29 @@ public:
|
||||
#if PK_DEBUG_CEVAL_STEP
|
||||
void __log_s_data(const char* title = nullptr);
|
||||
#endif
|
||||
PyObject* __py_exec_internal(const CodeObject_& code, PyObject* globals, PyObject* locals);
|
||||
PyVar __py_exec_internal(const CodeObject_& code, PyVar globals, PyVar locals);
|
||||
void __breakpoint();
|
||||
PyObject* __format_object(PyObject*, Str);
|
||||
PyObject* __run_top_frame();
|
||||
PyVar __format_object(PyVar, Str);
|
||||
PyVar __run_top_frame();
|
||||
void __pop_frame();
|
||||
PyObject* __py_generator(Frame&& frame, ArgsView buffer);
|
||||
PyVar __py_generator(Frame&& frame, ArgsView buffer);
|
||||
void __op_unpack_sequence(uint16_t arg);
|
||||
void __prepare_py_call(PyObject**, ArgsView, ArgsView, const FuncDecl_&);
|
||||
void __prepare_py_call(PyVar*, ArgsView, ArgsView, const FuncDecl_&);
|
||||
void __unpack_as_list(ArgsView args, List& list);
|
||||
void __unpack_as_dict(ArgsView args, Dict& dict);
|
||||
void __raise_exc(bool re_raise=false);
|
||||
void __init_builtin_types();
|
||||
void __post_init_builtin_types();
|
||||
void __builtin_error(StrName type);
|
||||
void __builtin_error(StrName type, PyObject* arg);
|
||||
void __builtin_error(StrName type, PyVar arg);
|
||||
void __builtin_error(StrName type, const Str& msg);
|
||||
void __push_varargs(){}
|
||||
void __push_varargs(PyObject* _0){ PUSH(_0); }
|
||||
void __push_varargs(PyObject* _0, PyObject* _1){ PUSH(_0); PUSH(_1); }
|
||||
void __push_varargs(PyObject* _0, PyObject* _1, PyObject* _2){ PUSH(_0); PUSH(_1); PUSH(_2); }
|
||||
void __push_varargs(PyObject* _0, PyObject* _1, PyObject* _2, PyObject* _3){ PUSH(_0); PUSH(_1); PUSH(_2); PUSH(_3); }
|
||||
PyObject* __pack_next_retval(unsigned);
|
||||
PyObject* __minmax_reduce(bool (VM::*op)(PyObject*, PyObject*), PyObject* args, PyObject* key);
|
||||
void __push_varargs(PyVar _0){ PUSH(_0); }
|
||||
void __push_varargs(PyVar _0, PyVar _1){ PUSH(_0); PUSH(_1); }
|
||||
void __push_varargs(PyVar _0, PyVar _1, PyVar _2){ PUSH(_0); PUSH(_1); PUSH(_2); }
|
||||
void __push_varargs(PyVar _0, PyVar _1, PyVar _2, PyVar _3){ PUSH(_0); PUSH(_1); PUSH(_2); PUSH(_3); }
|
||||
PyVar __pack_next_retval(unsigned);
|
||||
PyVar __minmax_reduce(bool (VM::*op)(PyVar, PyVar), PyVar args, PyVar key);
|
||||
};
|
||||
|
||||
|
||||
@ -464,10 +464,10 @@ template<> constexpr Type _find_type_in_const_cxx_typeid_map<StaticMethod>(){ re
|
||||
template<> constexpr Type _find_type_in_const_cxx_typeid_map<ClassMethod>(){ return VM::tp_classmethod; }
|
||||
|
||||
template<typename __T>
|
||||
PyObject* py_var(VM* vm, __T&& value){
|
||||
PyVar py_var(VM* vm, __T&& value){
|
||||
using T = std::decay_t<__T>;
|
||||
|
||||
static_assert(!std::is_same_v<T, PyObject*>, "py_var(VM*, PyObject*) is not allowed");
|
||||
static_assert(!std::is_same_v<T, PyVar>, "py_var(VM*, PyVar) is not allowed");
|
||||
|
||||
if constexpr(std::is_same_v<T, const char*> || std::is_same_v<T, std::string> || std::is_same_v<T, std::string_view>){
|
||||
// str (shortcuts)
|
||||
@ -483,7 +483,7 @@ PyObject* py_var(VM* vm, __T&& value){
|
||||
i64 val = static_cast<i64>(std::forward<__T>(value));
|
||||
if(val >= Number::kMinSmallInt && val <= Number::kMaxSmallInt){
|
||||
val = (val << 2) | 0b10;
|
||||
return reinterpret_cast<PyObject*>(val);
|
||||
return reinterpret_cast<PyVar>(val);
|
||||
}else{
|
||||
return vm->heap.gcnew<i64>(vm->tp_int, val);
|
||||
}
|
||||
@ -504,7 +504,7 @@ PyObject* py_var(VM* vm, __T&& value){
|
||||
}
|
||||
|
||||
template<typename __T, bool with_check>
|
||||
__T _py_cast__internal(VM* vm, PyObject* obj) {
|
||||
__T _py_cast__internal(VM* vm, PyVar obj) {
|
||||
static_assert(!std::is_rvalue_reference_v<__T>, "rvalue reference is not allowed");
|
||||
|
||||
using T = std::decay_t<__T>;
|
||||
@ -569,13 +569,13 @@ __T _py_cast__internal(VM* vm, PyObject* obj) {
|
||||
}
|
||||
|
||||
template<typename __T>
|
||||
__T py_cast(VM* vm, PyObject* obj) { return _py_cast__internal<__T, true>(vm, obj); }
|
||||
__T py_cast(VM* vm, PyVar obj) { return _py_cast__internal<__T, true>(vm, obj); }
|
||||
template<typename __T>
|
||||
__T _py_cast(VM* vm, PyObject* obj) { return _py_cast__internal<__T, false>(vm, obj); }
|
||||
__T _py_cast(VM* vm, PyVar obj) { return _py_cast__internal<__T, false>(vm, obj); }
|
||||
|
||||
template<typename T>
|
||||
PyObject* VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled){
|
||||
PyObject* type = new_type_object(mod, name, base, subclass_enabled);
|
||||
PyVar VM::register_user_class(PyVar mod, StrName name, RegisterFunc _register, Type base, bool subclass_enabled){
|
||||
PyVar type = new_type_object(mod, name, base, subclass_enabled);
|
||||
mod->attr().set(name, type);
|
||||
_cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type);
|
||||
_register(this, mod, type);
|
||||
@ -593,7 +593,7 @@ PyObject* VM::register_user_class(PyObject* mod, StrName name, RegisterFunc _reg
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
PyObject* VM::register_user_class(PyObject* mod, StrName name, Type base, bool subclass_enabled){
|
||||
PyVar VM::register_user_class(PyVar mod, StrName name, Type base, bool subclass_enabled){
|
||||
return register_user_class<T>(mod, name, &T::_register, base, subclass_enabled);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user