From ca8fd6b7b1f482328f1d004dae015d4e595eb63f Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 13 May 2023 12:36:52 +0800 Subject: [PATCH] ... --- src/cffi.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/common.h | 2 +- src/obj.h | 7 +++++- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/src/cffi.h b/src/cffi.h index 87d92110..60691518 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -49,6 +49,26 @@ struct VoidP{ } }; +struct PlainOldData{ + PY_CLASS(PlainOldData, c, pod) + + char* p; + + template + PlainOldData(const T& data){ + static_assert(std::is_pod_v); + p = new char[sizeof(T)]; + memcpy(p, &data, sizeof(T)); + } + + PlainOldData(): p(nullptr){} + ~PlainOldData(){ delete[] p; } + + static void _register(VM* vm, PyObject* mod, PyObject* type){ + vm->bind_default_constructor(type); + } +}; + inline void add_module_c(VM* vm){ PyObject* mod = vm->new_module("c"); VoidP::register_class(vm, mod); @@ -68,4 +88,44 @@ T to_void_p(VM* vm, PyObject* var){ VoidP& p = CAST(VoidP&, var); return reinterpret_cast(p.ptr); } + +template +T to_plain_old_data(VM* vm, PyObject* var){ + static_assert(std::is_pod_v); + PlainOldData& pod = CAST(PlainOldData&, var); + return *reinterpret_cast(pod.p); +} + +template +std::enable_if_t, PyObject*> py_var(VM* vm, const T& data){ + return VAR_T(PlainOldData, data); +} +/*****************************************************************/ +template +struct NativeProxyFuncC { + static constexpr int N = sizeof...(Params); + using _Fp = Ret(*)(Params...); + _Fp func; + NativeProxyFuncC(_Fp func) : func(func) {} + + PyObject* operator()(VM* vm, ArgsView args) { + if (args.size() != N) { + vm->TypeError("expected " + std::to_string(N) + " arguments, but got " + std::to_string(args.size())); + } + return call(vm, args, std::make_index_sequence()); + } + + template + std::enable_if_t, PyObject*> call(VM* vm, ArgsView args, std::index_sequence) { + func(py_cast(vm, args[Is])...); + return vm->None; + } + + template + std::enable_if_t, PyObject*> call(VM* vm, ArgsView args, std::index_sequence) { + __Ret ret = func(py_cast(vm, args[Is])...); + return VAR(std::move(ret)); + } +}; + } // namespace pkpy \ No newline at end of file diff --git a/src/common.h b/src/common.h index 0dea876f..8851cc0b 100644 --- a/src/common.h +++ b/src/common.h @@ -29,7 +29,7 @@ #include #include -#define PK_VERSION "0.9.9" +#define PK_VERSION "1.0.0" // debug macros #define DEBUG_NO_BUILTIN_MODULES 0 diff --git a/src/obj.h b/src/obj.h index 13d65a0d..c8a1f851 100644 --- a/src/obj.h +++ b/src/obj.h @@ -224,6 +224,7 @@ template struct is_py_class : std::false_type {}; template struct is_py_class> : std::true_type {}; template T to_void_p(VM*, PyObject*); +template T to_plain_old_data(VM*, PyObject*); template __T py_cast(VM* vm, PyObject* obj) { @@ -233,6 +234,8 @@ __T py_cast(VM* vm, PyObject* obj) { }else if constexpr(is_py_class::value){ T::_check_type(vm, obj); return OBJ_GET(T, obj); + }else if constexpr(std::is_pod_v){ + return to_plain_old_data(vm, obj); }else { return Discarded(); } @@ -245,7 +248,9 @@ __T _py_cast(VM* vm, PyObject* obj) { return to_void_p<__T>(vm, obj); }else if constexpr(is_py_class::value){ return OBJ_GET(T, obj); - }else{ + }else if constexpr(std::is_pod_v){ + return to_plain_old_data(vm, obj); + }else { return Discarded(); } }