obj.h 11 KB

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