kernel.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #pragma once
  2. #include <vector>
  3. #include <cassert>
  4. #include <pocketpy.h>
  5. #include "type_traits.h"
  6. namespace pybind11::impl {
  7. struct capsule {
  8. void* ptr;
  9. void (*destructor)(void*);
  10. template <typename T, typename = std::enable_if_t<!(std::is_same_v<remove_cvref_t<T>, capsule>)>>
  11. capsule(T&& value) :
  12. ptr(new auto(std::forward<T>(value))), destructor([](void* ptr) {
  13. delete static_cast<std::decay_t<T>*>(ptr);
  14. }) {}
  15. capsule(void* ptr, void (*destructor)(void*)) : ptr(ptr), destructor(destructor) {}
  16. capsule(const capsule&) = delete;
  17. capsule(capsule&& other) noexcept : ptr(other.ptr), destructor(other.destructor) {
  18. other.ptr = nullptr;
  19. other.destructor = nullptr;
  20. }
  21. ~capsule() {
  22. if(ptr && destructor) destructor(ptr);
  23. }
  24. };
  25. } // namespace pybind11::impl
  26. namespace pybind11 {
  27. class handle;
  28. class object;
  29. class iterator;
  30. class str;
  31. struct arg;
  32. struct args_proxy;
  33. struct kwargs_proxy;
  34. inline pkpy::VM* vm = nullptr;
  35. class interpreter {
  36. inline static std::vector<impl::capsule>* _capsules = nullptr;
  37. inline static std::vector<void (*)()>* _init = nullptr;
  38. public:
  39. inline static void initialize(bool enable_os = true) {
  40. if(vm == nullptr) {
  41. vm = new pkpy::VM();
  42. if(_init != nullptr) {
  43. for(auto& fn: *_init)
  44. fn();
  45. }
  46. }
  47. }
  48. inline static void finalize() {
  49. if(_capsules != nullptr) {
  50. delete _capsules;
  51. _capsules = nullptr;
  52. }
  53. if(vm != nullptr) {
  54. delete vm;
  55. vm = nullptr;
  56. }
  57. }
  58. template <typename T>
  59. inline static void* take_ownership(T&& value) {
  60. if(_capsules == nullptr) _capsules = new std::vector<impl::capsule>();
  61. _capsules->emplace_back(std::forward<T>(value));
  62. return _capsules->back().ptr;
  63. }
  64. inline static void register_init(void (*init)()) {
  65. if(_init == nullptr) _init = new std::vector<void (*)()>();
  66. _init->push_back(init);
  67. }
  68. inline static pkpy::PyVar bind_func(pkpy::PyVar scope,
  69. pkpy::StrName name,
  70. int argc,
  71. pkpy::NativeFuncC fn,
  72. pkpy::any any = {},
  73. pkpy::BindType type = pkpy::BindType::DEFAULT) {
  74. #if PK_VERSION_MAJOR == 2
  75. return vm->bind_func(scope.get(), name, argc, fn, any, type);
  76. #else
  77. return vm->bind_func(scope, name, argc, fn, std::move(any), type);
  78. #endif
  79. }
  80. template <typename... Args>
  81. inline static handle vectorcall(const handle& self, const handle& func, const Args&... args);
  82. };
  83. template <typename T>
  84. constexpr inline bool need_host = !(std::is_trivially_copyable_v<T> && (sizeof(T) <= 8));
  85. template <typename T>
  86. decltype(auto) unpack(pkpy::ArgsView view) {
  87. if constexpr(need_host<T>) {
  88. void* data = pkpy::lambda_get_userdata<void*>(view.begin());
  89. return *static_cast<T*>(data);
  90. } else {
  91. return pkpy::lambda_get_userdata<T>(view.begin());
  92. }
  93. }
  94. template <typename policy>
  95. class accessor;
  96. namespace policy {
  97. struct attr;
  98. struct item;
  99. struct tuple;
  100. struct list;
  101. struct dict;
  102. } // namespace policy
  103. using attr_accessor = accessor<policy::attr>;
  104. using item_accessor = accessor<policy::item>;
  105. using tuple_accessor = accessor<policy::tuple>;
  106. using list_accessor = accessor<policy::list>;
  107. using dict_accessor = accessor<policy::dict>;
  108. template <typename T>
  109. T cast(const handle& obj, bool convert = false);
  110. enum class return_value_policy : uint8_t {
  111. /**
  112. * This is the default return value policy, which falls back to the policy
  113. * return_value_policy::take_ownership when the return value is a pointer.
  114. * Otherwise, it uses return_value::move or return_value::copy for rvalue
  115. * and lvalue references, respectively. See below for a description of what
  116. * all of these different policies do.
  117. */
  118. automatic = 0,
  119. /**
  120. * As above, but use policy return_value_policy::reference when the return
  121. * value is a pointer. This is the default conversion policy for function
  122. * arguments when calling Python functions manually from C++ code (i.e. via
  123. * handle::operator()). You probably won't need to use this.
  124. */
  125. automatic_reference,
  126. /**
  127. * Reference an existing object (i.e. do not create a new copy) and take
  128. * ownership. Python will call the destructor and delete operator when the
  129. * object's reference count reaches zero. Undefined behavior ensues when
  130. * the C++ side does the same..
  131. */
  132. take_ownership,
  133. /**
  134. * Create a new copy of the returned object, which will be owned by
  135. * Python. This policy is comparably safe because the lifetimes of the two
  136. * instances are decoupled.
  137. */
  138. copy,
  139. /**
  140. * Use std::move to move the return value contents into a new instance
  141. * that will be owned by Python. This policy is comparably safe because the
  142. * lifetimes of the two instances (move source and destination) are
  143. * decoupled.
  144. */
  145. move,
  146. /**
  147. * Reference an existing object, but do not take ownership. The C++ side
  148. * is responsible for managing the object's lifetime and deallocating it
  149. * when it is no longer used. Warning: undefined behavior will ensue when
  150. * the C++ side deletes an object that is still referenced and used by
  151. * Python.
  152. */
  153. reference,
  154. /**
  155. * This policy only applies to methods and properties. It references the
  156. * object without taking ownership similar to the above
  157. * return_value_policy::reference policy. In contrast to that policy, the
  158. * function or property's implicit this argument (called the parent) is
  159. * considered to be the the owner of the return value (the child).
  160. * pybind11 then couples the lifetime of the parent to the child via a
  161. * reference relationship that ensures that the parent cannot be garbage
  162. * collected while Python is still using the child. More advanced
  163. * variations of this scheme are also possible using combinations of
  164. * return_value_policy::reference and the keep_alive call policy
  165. */
  166. reference_internal
  167. };
  168. struct empty {};
  169. template <typename... Args>
  170. void print(Args&&... args);
  171. class object;
  172. template <typename T>
  173. constexpr inline bool is_pyobject_v = std::is_base_of_v<object, T>;
  174. #if PK_VERSION_MAJOR == 2
  175. using error_already_set = pkpy::TopLevelException;
  176. #else
  177. using error_already_set = pkpy::Exception;
  178. #endif
  179. inline void setattr(const handle& obj, const handle& name, const handle& value);
  180. inline void setattr(const handle& obj, const char* name, const handle& value);
  181. } // namespace pybind11