obj.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. #pragma once
  2. #include "common.h"
  3. #include "namedict.h"
  4. #include "tuplelist.h"
  5. namespace pkpy {
  6. struct Frame;
  7. class VM;
  8. #if PK_ENABLE_STD_FUNCTION
  9. using NativeFuncC = std::function<PyObject*(VM*, ArgsView)>;
  10. #else
  11. typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
  12. #endif
  13. enum class BindType{
  14. DEFAULT,
  15. STATICMETHOD,
  16. CLASSMETHOD,
  17. };
  18. struct BoundMethod {
  19. PyObject* self;
  20. PyObject* func;
  21. BoundMethod(PyObject* self, PyObject* func) : self(self), func(func) {}
  22. };
  23. struct StaticMethod{
  24. PyObject* func;
  25. StaticMethod(PyObject* func) : func(func) {}
  26. };
  27. struct ClassMethod{
  28. PyObject* func;
  29. ClassMethod(PyObject* func) : func(func) {}
  30. };
  31. struct Property{
  32. PyObject* getter;
  33. PyObject* setter;
  34. Str signature;
  35. Property(PyObject* getter, PyObject* setter, Str signature) : getter(getter), setter(setter), signature(signature) {}
  36. };
  37. struct Range {
  38. i64 start = 0;
  39. i64 stop = -1;
  40. i64 step = 1;
  41. };
  42. struct StarWrapper{
  43. int level; // either 1 or 2
  44. PyObject* obj;
  45. StarWrapper(int level, PyObject* obj) : level(level), obj(obj) {}
  46. };
  47. struct Bytes{
  48. unsigned char* _data;
  49. int _size;
  50. int size() const noexcept { return _size; }
  51. int operator[](int i) const noexcept { return (int)_data[i]; }
  52. const unsigned char* data() const noexcept { return _data; }
  53. bool operator==(const Bytes& rhs) const;
  54. bool operator!=(const Bytes& rhs) const;
  55. Str str() const noexcept { return Str((char*)_data, _size); }
  56. std::string_view sv() const noexcept { return std::string_view((char*)_data, _size); }
  57. Bytes() : _data(nullptr), _size(0) {}
  58. Bytes(unsigned char* p, int size): _data(p), _size(size) {}
  59. Bytes(const Str& str): Bytes(str.sv()) {}
  60. operator bool() const noexcept { return _data != nullptr; }
  61. Bytes(const std::vector<unsigned char>& v);
  62. Bytes(std::string_view sv);
  63. Bytes(const Bytes& rhs);
  64. Bytes(Bytes&& rhs) noexcept;
  65. Bytes& operator=(Bytes&& rhs) noexcept;
  66. Bytes& operator=(const Bytes& rhs) = delete;
  67. std::pair<unsigned char*, int> detach() noexcept;
  68. ~Bytes(){ delete[] _data;}
  69. };
  70. using Super = std::pair<PyObject*, Type>;
  71. struct Slice {
  72. PyObject* start;
  73. PyObject* stop;
  74. PyObject* step;
  75. Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {}
  76. };
  77. struct GCHeader {
  78. bool enabled; // whether this object is managed by GC
  79. bool marked; // whether this object is marked
  80. GCHeader() : enabled(true), marked(false) {}
  81. };
  82. struct PyObject{
  83. GCHeader gc;
  84. Type type;
  85. NameDict* _attr;
  86. bool is_attr_valid() const noexcept { return _attr != nullptr; }
  87. NameDict& attr() noexcept { return *_attr; }
  88. PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
  89. // PyObject* operator[](StrName name) const noexcept { return (*_attr)[name]; }
  90. virtual void _obj_gc_mark() = 0;
  91. virtual void* _value_ptr() = 0;
  92. PyObject(Type type) : type(type), _attr(nullptr) {}
  93. virtual ~PyObject();
  94. void _enable_instance_dict() {
  95. _attr = new(pool128_alloc<NameDict>()) NameDict();
  96. }
  97. void _enable_instance_dict(float lf){
  98. _attr = new(pool128_alloc<NameDict>()) NameDict(lf);
  99. }
  100. };
  101. struct PySignalObject: PyObject {
  102. PySignalObject() : PyObject(0) {
  103. gc.enabled = false;
  104. }
  105. void _obj_gc_mark() override {}
  106. void* _value_ptr() override { return nullptr; }
  107. };
  108. inline PyObject* const PY_NULL = new PySignalObject();
  109. inline PyObject* const PY_OP_CALL = new PySignalObject();
  110. inline PyObject* const PY_OP_YIELD = new PySignalObject();
  111. const int kTpIntIndex = 2;
  112. const int kTpFloatIndex = 3;
  113. inline bool is_tagged(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) != 0b00; }
  114. inline bool is_small_int(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) == 0b10; }
  115. inline bool is_heap_int(PyObject* p) noexcept { return !is_tagged(p) && p->type.index == kTpIntIndex; }
  116. inline bool is_float(PyObject* p) noexcept { return (PK_BITS(p) & 1) == 1; } // 01 or 11
  117. inline bool is_int(PyObject* p) noexcept { return is_small_int(p) || is_heap_int(p); }
  118. inline bool is_type(PyObject* obj, Type type) {
  119. #if PK_DEBUG_EXTRA_CHECK
  120. if(obj == nullptr) throw std::runtime_error("is_type() called with nullptr");
  121. #endif
  122. switch(type.index){
  123. case kTpIntIndex: return is_int(obj);
  124. case kTpFloatIndex: return is_float(obj);
  125. default: return !is_tagged(obj) && obj->type == type;
  126. }
  127. }
  128. inline bool is_non_tagged_type(PyObject* obj, Type type) {
  129. #if PK_DEBUG_EXTRA_CHECK
  130. if(obj == nullptr) throw std::runtime_error("is_non_tagged_type() called with nullptr");
  131. #endif
  132. return !is_tagged(obj) && obj->type == type;
  133. }
  134. template <typename, typename=void> struct has_gc_marker : std::false_type {};
  135. template <typename T> struct has_gc_marker<T, std::void_t<decltype(&T::_gc_mark)>> : std::true_type {};
  136. template <typename T>
  137. struct Py_ final: PyObject {
  138. T _value;
  139. void _obj_gc_mark() override {
  140. if constexpr (has_gc_marker<T>::value) {
  141. _value._gc_mark();
  142. }
  143. }
  144. void* _value_ptr() override { return &_value; }
  145. template <typename... Args>
  146. Py_(Type type, Args&&... args) : PyObject(type), _value(std::forward<Args>(args)...) { }
  147. };
  148. struct MappingProxy{
  149. PyObject* obj;
  150. MappingProxy(PyObject* obj) : obj(obj) {}
  151. NameDict& attr() noexcept { return obj->attr(); }
  152. };
  153. #define PK_OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
  154. #define PK_OBJ_MARK(obj) \
  155. if(!is_tagged(obj) && !(obj)->gc.marked) { \
  156. (obj)->gc.marked = true; \
  157. (obj)->_obj_gc_mark(); \
  158. if((obj)->is_attr_valid()) gc_mark_namedict((obj)->attr()); \
  159. }
  160. inline void gc_mark_namedict(NameDict& t){
  161. if(t.size() == 0) return;
  162. t.apply([](StrName name, PyObject* obj){
  163. PK_OBJ_MARK(obj);
  164. });
  165. }
  166. StrName obj_type_name(VM* vm, Type type);
  167. #if PK_DEBUG_NO_BUILTINS
  168. #define OBJ_NAME(obj) Str("<?>")
  169. #else
  170. #define OBJ_NAME(obj) PK_OBJ_GET(Str, vm->getattr(obj, __name__))
  171. #endif
  172. template <typename, typename=void> struct is_py_class : std::false_type {};
  173. template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {};
  174. template<typename T> T to_void_p(VM*, PyObject*);
  175. template<typename __T>
  176. __T py_cast(VM* vm, PyObject* obj) {
  177. using T = std::decay_t<__T>;
  178. if constexpr(std::is_enum_v<T>){
  179. return (__T)py_cast<i64>(vm, obj);
  180. }else if constexpr(std::is_pointer_v<T>){
  181. return to_void_p<T>(vm, obj);
  182. }else if constexpr(is_py_class<T>::value){
  183. T::_check_type(vm, obj);
  184. return PK_OBJ_GET(T, obj);
  185. }else {
  186. return Discarded();
  187. }
  188. }
  189. template<typename __T>
  190. __T _py_cast(VM* vm, PyObject* obj) {
  191. using T = std::decay_t<__T>;
  192. if constexpr(std::is_enum_v<T>){
  193. return (__T)_py_cast<i64>(vm, obj);
  194. }else if constexpr(std::is_pointer_v<__T>){
  195. return to_void_p<__T>(vm, obj);
  196. }else if constexpr(is_py_class<T>::value){
  197. return PK_OBJ_GET(T, obj);
  198. }else {
  199. return Discarded();
  200. }
  201. }
  202. #define VAR(x) py_var(vm, x)
  203. #define CAST(T, x) py_cast<T>(vm, x)
  204. #define _CAST(T, x) _py_cast<T>(vm, x)
  205. #define CAST_F(x) py_cast<f64>(vm, x)
  206. #define CAST_DEFAULT(T, x, default_value) (x != vm->None) ? py_cast<T>(vm, x) : (default_value)
  207. /*****************************************************************/
  208. template<>
  209. struct Py_<i64> final: PyObject {
  210. i64 _value;
  211. Py_(Type type, i64 val): PyObject(type), _value(val) {}
  212. void _obj_gc_mark() override {}
  213. void* _value_ptr() override { return &_value; }
  214. };
  215. inline bool try_cast_int(PyObject* obj, i64* val) noexcept {
  216. if(is_small_int(obj)){
  217. *val = PK_BITS(obj) >> 2;
  218. return true;
  219. }else if(is_heap_int(obj)){
  220. *val = PK_OBJ_GET(i64, obj);
  221. return true;
  222. }else{
  223. return false;
  224. }
  225. }
  226. template<>
  227. struct Py_<List> final: PyObject {
  228. List _value;
  229. Py_(Type type, List&& val): PyObject(type), _value(std::move(val)) {}
  230. Py_(Type type, const List& val): PyObject(type), _value(val) {}
  231. void _obj_gc_mark() override {
  232. for(PyObject* obj: _value) PK_OBJ_MARK(obj);
  233. }
  234. void* _value_ptr() override { return &_value; }
  235. };
  236. template<>
  237. struct Py_<Tuple> final: PyObject {
  238. Tuple _value;
  239. Py_(Type type, Tuple&& val): PyObject(type), _value(std::move(val)) {}
  240. Py_(Type type, const Tuple& val): PyObject(type), _value(val) {}
  241. void _obj_gc_mark() override {
  242. for(PyObject* obj: _value) PK_OBJ_MARK(obj);
  243. }
  244. void* _value_ptr() override { return &_value; }
  245. };
  246. template<>
  247. struct Py_<MappingProxy> final: PyObject {
  248. MappingProxy _value;
  249. Py_(Type type, MappingProxy val): PyObject(type), _value(val) {}
  250. void _obj_gc_mark() override {
  251. PK_OBJ_MARK(_value.obj);
  252. }
  253. void* _value_ptr() override { return &_value; }
  254. };
  255. template<>
  256. struct Py_<BoundMethod> final: PyObject {
  257. BoundMethod _value;
  258. Py_(Type type, BoundMethod val): PyObject(type), _value(val) {}
  259. void _obj_gc_mark() override {
  260. PK_OBJ_MARK(_value.self);
  261. PK_OBJ_MARK(_value.func);
  262. }
  263. void* _value_ptr() override { return &_value; }
  264. };
  265. template<>
  266. struct Py_<StarWrapper> final: PyObject {
  267. StarWrapper _value;
  268. Py_(Type type, StarWrapper val): PyObject(type), _value(val) {}
  269. void _obj_gc_mark() override {
  270. PK_OBJ_MARK(_value.obj);
  271. }
  272. void* _value_ptr() override { return &_value; }
  273. };
  274. template<>
  275. struct Py_<StaticMethod> final: PyObject {
  276. StaticMethod _value;
  277. Py_(Type type, StaticMethod val): PyObject(type), _value(val) {}
  278. void _obj_gc_mark() override {
  279. PK_OBJ_MARK(_value.func);
  280. }
  281. void* _value_ptr() override { return &_value; }
  282. };
  283. template<>
  284. struct Py_<ClassMethod> final: PyObject {
  285. ClassMethod _value;
  286. Py_(Type type, ClassMethod val): PyObject(type), _value(val) {}
  287. void _obj_gc_mark() override {
  288. PK_OBJ_MARK(_value.func);
  289. }
  290. void* _value_ptr() override { return &_value; }
  291. };
  292. template<>
  293. struct Py_<Property> final: PyObject {
  294. Property _value;
  295. Py_(Type type, Property val): PyObject(type), _value(val) {}
  296. void _obj_gc_mark() override {
  297. PK_OBJ_MARK(_value.getter);
  298. PK_OBJ_MARK(_value.setter);
  299. }
  300. void* _value_ptr() override { return &_value; }
  301. };
  302. template<>
  303. struct Py_<Slice> final: PyObject {
  304. Slice _value;
  305. Py_(Type type, Slice val): PyObject(type), _value(val) {}
  306. void _obj_gc_mark() override {
  307. PK_OBJ_MARK(_value.start);
  308. PK_OBJ_MARK(_value.stop);
  309. PK_OBJ_MARK(_value.step);
  310. }
  311. void* _value_ptr() override { return &_value; }
  312. };
  313. template<>
  314. struct Py_<Super> final: PyObject {
  315. Super _value;
  316. template<typename... Args>
  317. Py_(Type type, Args&&... args): PyObject(type), _value(std::forward<Args>(args)...) {}
  318. void _obj_gc_mark() override {
  319. PK_OBJ_MARK(_value.first);
  320. }
  321. void* _value_ptr() override { return &_value; }
  322. };
  323. template<>
  324. struct Py_<DummyInstance> final: PyObject {
  325. Py_(Type type): PyObject(type) {
  326. _enable_instance_dict();
  327. }
  328. void _obj_gc_mark() override {}
  329. void* _value_ptr() override { return nullptr; }
  330. };
  331. template<>
  332. struct Py_<Type> final: PyObject {
  333. Type _value;
  334. Py_(Type type, Type val): PyObject(type), _value(val) {
  335. _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR);
  336. }
  337. void _obj_gc_mark() override {}
  338. void* _value_ptr() override { return &_value; }
  339. };
  340. template<>
  341. struct Py_<DummyModule> final: PyObject {
  342. Py_(Type type): PyObject(type) {
  343. _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR);
  344. }
  345. void _obj_gc_mark() override {}
  346. void* _value_ptr() override { return nullptr; }
  347. };
  348. } // namespace pkpy