mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
some fix
This commit is contained in:
parent
83ca79e5f7
commit
fa73e3122f
@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "cffi.h"
|
#include "cffi.h"
|
||||||
|
#include "vm.h"
|
||||||
|
|
||||||
namespace pkpy{
|
namespace pkpy{
|
||||||
|
|
||||||
struct NativeProxyFuncCBase {
|
struct NativeProxyFuncCBase {
|
||||||
virtual PyObject* operator()(VM* vm, ArgsView args) = 0;
|
virtual PyObject* operator()(VM* vm, ArgsView args) = 0;
|
||||||
};
|
};
|
||||||
@ -56,62 +56,63 @@ struct NativeProxyMethodC final: NativeProxyFuncCBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*****************************************************************/
|
||||||
inline PyObject* proxy_wrapper(VM* vm, ArgsView args){
|
inline PyObject* __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>
|
||||||
void _bind(VM* vm, PyObject* obj, const char* sig, Ret(*func)(Params...)){
|
PyObject* VM::bind(PyObject* obj, const char* sig, Ret(*func)(Params...), BindType bt){
|
||||||
auto proxy = new NativeProxyFuncC<Ret, Params...>(func);
|
auto proxy = new NativeProxyFuncC<Ret, Params...>(func);
|
||||||
vm->bind(obj, sig, proxy_wrapper, proxy);
|
return vm->bind(obj, sig, __proxy_wrapper, proxy, bt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Ret, typename T, typename... Params>
|
template<typename Ret, typename T, typename... Params>
|
||||||
void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
|
PyObject* VM::bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...), BindType bt){
|
||||||
auto proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
|
auto proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
|
||||||
vm->bind(obj, sig, proxy_wrapper, proxy);
|
return vm->bind(obj, sig, __proxy_wrapper, proxy, bt);
|
||||||
}
|
}
|
||||||
/*****************************************************************/
|
|
||||||
#define PY_FIELD_EX(T, NAME, REF, EXPR) \
|
|
||||||
vm->bind_property(type, NAME, \
|
|
||||||
[](VM* vm, ArgsView args){ \
|
|
||||||
T& self = PK_OBJ_GET(T, args[0]); \
|
|
||||||
return VAR(self.REF()->EXPR); \
|
|
||||||
}, \
|
|
||||||
[](VM* vm, ArgsView args){ \
|
|
||||||
T& self = PK_OBJ_GET(T, args[0]); \
|
|
||||||
self.REF()->EXPR = CAST(decltype(self.REF()->EXPR), args[1]); \
|
|
||||||
return vm->None; \
|
|
||||||
});
|
|
||||||
|
|
||||||
#define PY_READONLY_FIELD_EX(T, NAME, REF, EXPR) \
|
template<typename Ret, typename... Params>
|
||||||
vm->bind_property(type, NAME, \
|
PyObject* VM::bind(PyObject* obj, const char* sig, const char* docstring, Ret(*func)(Params...), BindType bt){
|
||||||
[](VM* vm, ArgsView args){ \
|
auto proxy = new NativeProxyFuncC<Ret, Params...>(func);
|
||||||
T& self = PK_OBJ_GET(T, args[0]); \
|
return vm->bind(obj, sig, docstring, __proxy_wrapper, proxy, bt);
|
||||||
return VAR(self.REF()->EXPR); \
|
}
|
||||||
});
|
|
||||||
|
|
||||||
#define PY_PROPERTY_EX(T, NAME, REF, FGET, FSET) \
|
template<typename Ret, typename T, typename... Params>
|
||||||
vm->bind_property(type, NAME, \
|
PyObject* VM::bind(VM* vm, PyObject* obj, const char* sig, const char* docstring, Ret(T::*func)(Params...), BindType bt){
|
||||||
[](VM* vm, ArgsView args){ \
|
auto proxy = new NativeProxyMethodC<Ret, T, Params...>(func);
|
||||||
T& self = PK_OBJ_GET(T, args[0]); \
|
return vm->bind(obj, sig, docstring, __proxy_wrapper, proxy, bt);
|
||||||
return VAR(self.REF()->FGET()); \
|
}
|
||||||
}, \
|
|
||||||
[](VM* vm, ArgsView args){ \
|
|
||||||
T& self = _CAST(T&, args[0]); \
|
|
||||||
using __NT = decltype(self.REF()->FGET()); \
|
|
||||||
self.REF()->FSET(CAST(__NT, args[1])); \
|
|
||||||
return vm->None; \
|
|
||||||
});
|
|
||||||
|
|
||||||
#define PY_READONLY_PROPERTY_EX(T, NAME, REF, FGET) \
|
template<typename T, typename F, bool ReadOnly>
|
||||||
vm->bind_property(type, NAME, \
|
PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){
|
||||||
[](VM* vm, ArgsView args){ \
|
static_assert(!std::is_reference_v<F>);
|
||||||
T& self = PK_OBJ_GET(T, args[0]); \
|
std::string_view name_sv(name); int pos = name_sv.find(':');
|
||||||
return VAR(self.REF()->FGET()); \
|
if(pos > 0) name_sv = name_sv.substr(0, pos);
|
||||||
});
|
auto fget = [](VM* vm, ArgsView args) -> PyObject*{
|
||||||
|
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, false);
|
||||||
|
PK_OBJ_GET(NativeFunc, _0).set_userdata(field);
|
||||||
|
PyObject* _1 = vm->None;
|
||||||
|
if constexpr (!ReadOnly){
|
||||||
|
auto fset = [](VM* vm, ArgsView args){
|
||||||
|
T& self = PK_OBJ_GET(T, args[0]);
|
||||||
|
F T::*field = lambda_get_userdata<F T::*>(args.begin());
|
||||||
|
self.*field = py_cast<F>(vm, args[1]);
|
||||||
|
return vm->None;
|
||||||
|
};
|
||||||
|
_1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, false);
|
||||||
|
PK_OBJ_GET(NativeFunc, _1).set_userdata(field);
|
||||||
|
}
|
||||||
|
PyObject* prop = VAR(Property(_0, _1));
|
||||||
|
obj->attr().set(StrName(name_sv), prop);
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
#define PY_FIELD(T, NAME, EXPR) \
|
#define PY_FIELD(T, NAME, EXPR) \
|
||||||
vm->bind_property(type, NAME, \
|
vm->bind_property(type, NAME, \
|
||||||
@ -152,7 +153,6 @@ void _bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...)){
|
|||||||
return VAR(self.FGET()); \
|
return VAR(self.FGET()); \
|
||||||
});
|
});
|
||||||
/*****************************************************************/
|
/*****************************************************************/
|
||||||
|
|
||||||
#define PY_STRUCT_LIKE(wT) \
|
#define PY_STRUCT_LIKE(wT) \
|
||||||
static_assert(std::is_trivially_copyable<wT>::value); \
|
static_assert(std::is_trivially_copyable<wT>::value); \
|
||||||
type->attr().set("__struct__", vm->True); \
|
type->attr().set("__struct__", vm->True); \
|
||||||
|
@ -302,6 +302,16 @@ public:
|
|||||||
}
|
}
|
||||||
PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
PyObject* bind(PyObject*, const char*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
||||||
PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
PyObject* bind(PyObject*, const char*, NativeFuncC, UserData userdata={}, BindType bt=BindType::DEFAULT);
|
||||||
|
|
||||||
|
template<typename Ret, typename... Params>
|
||||||
|
PyObject* bind(PyObject* obj, const char* sig, Ret(*func)(Params...), BindType bt=BindType::DEFAULT);
|
||||||
|
template<typename Ret, typename T, typename... Params>
|
||||||
|
PyObject* bind(VM* vm, PyObject* obj, const char* sig, Ret(T::*func)(Params...), BindType bt=BindType::DEFAULT);
|
||||||
|
template<typename Ret, typename... Params>
|
||||||
|
PyObject* bind(PyObject* obj, const char* sig, const char* docstring, Ret(*func)(Params...), BindType bt=BindType::DEFAULT);
|
||||||
|
template<typename Ret, typename T, typename... Params>
|
||||||
|
PyObject* bind(VM* vm, PyObject* obj, const char* sig, const char* docstring, Ret(T::*func)(Params...), BindType bt=BindType::DEFAULT);
|
||||||
|
|
||||||
PyObject* bind_property(PyObject*, const char*, NativeFuncC fget, NativeFuncC fset=nullptr);
|
PyObject* bind_property(PyObject*, 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::*);
|
PyObject* bind_field(PyObject*, const char*, F T::*);
|
||||||
@ -344,24 +354,8 @@ public:
|
|||||||
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(PyObject* obj){ return _tp(obj) == _tp_user<T>(); }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
PyObject* register_user_class(PyObject* mod, StrName name, bool subclass_enabled=false){
|
PyObject* register_user_class(PyObject* mod, StrName name, bool subclass_enabled=false);
|
||||||
PyObject* type = new_type_object(mod, name, 0, subclass_enabled);
|
|
||||||
mod->attr().set(name, type);
|
|
||||||
_cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type);
|
|
||||||
T::_register(vm, mod, type);
|
|
||||||
// check if T is trivially constructible
|
|
||||||
if constexpr(!std::is_default_constructible_v<T>){
|
|
||||||
if(!type->attr().contains(__new__)){
|
|
||||||
bind_func(type, __new__, -1, [](VM* vm, ArgsView args){
|
|
||||||
vm->NotImplementedError();
|
|
||||||
return vm->None;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename ...Args>
|
template<typename T, typename ...Args>
|
||||||
PyObject* new_user_object(Args&&... args){
|
PyObject* new_user_object(Args&&... args){
|
||||||
@ -548,32 +542,22 @@ __T py_cast(VM* vm, PyObject* obj) { return _py_cast__internal<__T, true>(vm, o
|
|||||||
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, PyObject* obj) { return _py_cast__internal<__T, false>(vm, obj); }
|
||||||
|
|
||||||
template<typename T, typename F, bool ReadOnly>
|
template<typename T>
|
||||||
PyObject* VM::bind_field(PyObject* obj, const char* name, F T::*field){
|
PyObject* VM::register_user_class(PyObject* mod, StrName name, bool subclass_enabled){
|
||||||
static_assert(!std::is_reference_v<F>);
|
PyObject* type = new_type_object(mod, name, 0, subclass_enabled);
|
||||||
std::string_view name_sv(name); int pos = name_sv.find(':');
|
mod->attr().set(name, type);
|
||||||
if(pos > 0) name_sv = name_sv.substr(0, pos);
|
_cxx_typeid_map[typeid(T)] = PK_OBJ_GET(Type, type);
|
||||||
auto fget = [](VM* vm, ArgsView args) -> PyObject*{
|
T::_register(vm, mod, type);
|
||||||
T& self = PK_OBJ_GET(T, args[0]);
|
// check if T is trivially constructible
|
||||||
F T::*field = lambda_get_userdata<F T::*>(args.begin());
|
if constexpr(!std::is_default_constructible_v<T>){
|
||||||
return VAR(self.*field);
|
if(!type->attr().contains(__new__)){
|
||||||
};
|
bind_func(type, __new__, -1, [](VM* vm, ArgsView args){
|
||||||
PyObject* _0 = heap.gcnew<NativeFunc>(tp_native_func, fget, 1, false);
|
vm->NotImplementedError();
|
||||||
PK_OBJ_GET(NativeFunc, _0).set_userdata(field);
|
return vm->None;
|
||||||
PyObject* _1 = vm->None;
|
});
|
||||||
if constexpr (!ReadOnly){
|
}
|
||||||
auto fset = [](VM* vm, ArgsView args){
|
|
||||||
T& self = PK_OBJ_GET(T, args[0]);
|
|
||||||
F T::*field = lambda_get_userdata<F T::*>(args.begin());
|
|
||||||
self.*field = py_cast<F>(vm, args[1]);
|
|
||||||
return vm->None;
|
|
||||||
};
|
|
||||||
_1 = heap.gcnew<NativeFunc>(tp_native_func, fset, 2, false);
|
|
||||||
PK_OBJ_GET(NativeFunc, _1).set_userdata(field);
|
|
||||||
}
|
}
|
||||||
PyObject* prop = VAR(Property(_0, _1));
|
return type;
|
||||||
obj->attr().set(StrName(name_sv), prop);
|
|
||||||
return prop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
Loading…
x
Reference in New Issue
Block a user