cffi.h 3.2 KB

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