cffi.hpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #pragma once
  2. #include "pocketpy/interpreter/vm.hpp"
  3. namespace pkpy {
  4. #define PY_CLASS(T, mod, name) \
  5. [[deprecated]] static Type _type(VM* vm) { return vm->_cxx_typeid_map[typeid(T)]; } \
  6. [[deprecated]] static PyVar register_class(VM* vm, PyVar mod, Type base = VM::tp_object) { \
  7. return vm->register_user_class<T>(mod, #name, base); \
  8. }
  9. struct VoidP {
  10. void* ptr;
  11. VoidP(const void* ptr) : ptr(const_cast<void*>(ptr)) {}
  12. bool operator== (const VoidP& other) const { return ptr == other.ptr; }
  13. bool operator!= (const VoidP& other) const { return ptr != other.ptr; }
  14. bool operator< (const VoidP& other) const { return ptr < other.ptr; }
  15. bool operator<= (const VoidP& other) const { return ptr <= other.ptr; }
  16. bool operator> (const VoidP& other) const { return ptr > other.ptr; }
  17. bool operator>= (const VoidP& other) const { return ptr >= other.ptr; }
  18. Str hex() const {
  19. SStream ss;
  20. ss.write_ptr(ptr);
  21. return ss.str();
  22. }
  23. static void _register(VM* vm, PyObject* mod, PyObject* type);
  24. };
  25. #define POINTER_VAR(Tp, NAME) \
  26. inline PyVar py_var(VM* vm, Tp val) { \
  27. const static pair<StrName, StrName> P("c", NAME); \
  28. PyVar type = vm->_modules[P.first]->attr(P.second); \
  29. return vm->new_object<VoidP>(type->as<Type>(), val); \
  30. }
  31. POINTER_VAR(char*, "char_p")
  32. // const char* is special, need to rethink about it
  33. POINTER_VAR(const unsigned char*, "uchar_p")
  34. POINTER_VAR(const short*, "short_p")
  35. POINTER_VAR(const unsigned short*, "ushort_p")
  36. POINTER_VAR(const int*, "int_p")
  37. POINTER_VAR(const unsigned int*, "uint_p")
  38. POINTER_VAR(const long*, "long_p")
  39. POINTER_VAR(const unsigned long*, "ulong_p")
  40. POINTER_VAR(const long long*, "longlong_p")
  41. POINTER_VAR(const unsigned long long*, "ulonglong_p")
  42. POINTER_VAR(const float*, "float_p")
  43. POINTER_VAR(const double*, "double_p")
  44. POINTER_VAR(const bool*, "bool_p")
  45. #undef POINTER_VAR
  46. struct Struct {
  47. constexpr static int INLINE_SIZE = 24;
  48. char _inlined[INLINE_SIZE];
  49. char* p;
  50. int size;
  51. Struct(int new_size, bool zero_init = true) {
  52. this->size = new_size;
  53. if(size <= INLINE_SIZE) {
  54. p = _inlined;
  55. } else {
  56. p = (char*)std::malloc(size);
  57. }
  58. if(zero_init) std::memset(p, 0, size);
  59. }
  60. Struct(void* p, int size) : Struct(size, false) {
  61. if(p != nullptr) std::memcpy(this->p, p, size);
  62. }
  63. Struct(const Struct& other) : Struct(other.p, other.size) {}
  64. ~Struct() {
  65. if(p != _inlined) std::free(p);
  66. }
  67. static void _register(VM* vm, PyObject* mod, PyObject* type);
  68. };
  69. /***********************************************/
  70. template <typename Tp>
  71. Tp to_void_p(VM* vm, PyVar var) {
  72. static_assert(std::is_pointer_v<Tp>);
  73. if(is_none(var)) return nullptr; // None can be casted to any pointer implicitly
  74. VoidP& p = CAST(VoidP&, var);
  75. return reinterpret_cast<Tp>(p.ptr);
  76. }
  77. /*****************************************************************/
  78. void add_module_c(VM* vm);
  79. } // namespace pkpy