cffi.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #pragma once
  2. #include "common.h"
  3. #include "vm.h"
  4. namespace pkpy {
  5. #define PY_CLASS(T, mod, name) \
  6. static Type _type(VM* vm) { \
  7. static const StrName __x0(#mod); \
  8. static const StrName __x1(#name); \
  9. return OBJ_GET(Type, vm->_modules[__x0]->attr(__x1)); \
  10. } \
  11. static PyObject* register_class(VM* vm, PyObject* mod) { \
  12. PyObject* type = vm->new_type_object(mod, #name, vm->tp_object); \
  13. if(OBJ_NAME(mod) != #mod) { \
  14. auto msg = fmt("register_class() failed: ", OBJ_NAME(mod), " != ", #mod); \
  15. throw std::runtime_error(msg); \
  16. } \
  17. T::_register(vm, mod, type); \
  18. type->attr()._try_perfect_rehash(); \
  19. return type; \
  20. }
  21. #define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), T(__VA_ARGS__))
  22. struct VoidP{
  23. PY_CLASS(VoidP, c, void_p)
  24. void* ptr;
  25. VoidP(void* ptr): ptr(ptr){}
  26. static void _register(VM* vm, PyObject* mod, PyObject* type){
  27. vm->bind_static_method<1>(type, "__new__", CPP_NOT_IMPLEMENTED());
  28. vm->bind_static_method<1>(type, "__repr__", [](VM* vm, ArgsView args){
  29. VoidP& self = CAST(VoidP&, args[0]);
  30. std::stringstream ss;
  31. ss << "<void* at " << self.ptr << ">";
  32. return VAR(ss.str());
  33. });
  34. }
  35. };
  36. inline void add_module_c(VM* vm){
  37. PyObject* mod = vm->new_module("c");
  38. VoidP::register_class(vm, mod);
  39. }
  40. inline PyObject* py_var(VM* vm, void* p){
  41. return VAR_T(VoidP, p);
  42. }
  43. inline PyObject* py_var(VM* vm, char* p){
  44. return VAR_T(VoidP, p);
  45. }
  46. /***********************************************/
  47. template<typename T>
  48. struct _pointer {
  49. static constexpr int level = 0;
  50. using baseT = T;
  51. };
  52. template<typename T>
  53. struct _pointer<T*> {
  54. static constexpr int level = _pointer<T>::level + 1;
  55. using baseT = typename _pointer<T>::baseT;
  56. };
  57. template<typename T>
  58. struct pointer {
  59. static constexpr int level = _pointer<std::decay_t<T>>::level;
  60. using baseT = typename _pointer<std::decay_t<T>>::baseT;
  61. };
  62. template<typename T>
  63. T py_pointer_cast(VM* vm, PyObject* var){
  64. static_assert(std::is_pointer_v<T>);
  65. VoidP& p = CAST(VoidP&, var);
  66. return reinterpret_cast<T>(p.ptr);
  67. }
  68. } // namespace pkpy