obj.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  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. Property(PyObject* getter, PyObject* setter) : getter(getter), setter(setter) {}
  35. };
  36. struct Range {
  37. i64 start = 0;
  38. i64 stop = -1;
  39. i64 step = 1;
  40. };
  41. struct StarWrapper{
  42. int level; // either 1 or 2
  43. PyObject* obj;
  44. StarWrapper(int level, PyObject* obj) : level(level), obj(obj) {}
  45. };
  46. struct Bytes{
  47. unsigned char* _data;
  48. int _size;
  49. int size() const noexcept { return _size; }
  50. int operator[](int i) const noexcept { return (int)_data[i]; }
  51. const unsigned char* data() const noexcept { return _data; }
  52. bool operator==(const Bytes& rhs) const;
  53. bool operator!=(const Bytes& rhs) const;
  54. Str str() const noexcept { return Str((char*)_data, _size); }
  55. std::string_view sv() const noexcept { return std::string_view((char*)_data, _size); }
  56. Bytes() : _data(nullptr), _size(0) {}
  57. Bytes(unsigned char* p, int size): _data(p), _size(size) {}
  58. Bytes(const Str& str): Bytes(str.sv()) {}
  59. operator bool() const noexcept { return _data != nullptr; }
  60. Bytes(std::string_view sv);
  61. Bytes(const Bytes& rhs);
  62. Bytes(Bytes&& rhs) noexcept;
  63. Bytes& operator=(Bytes&& rhs) noexcept;
  64. Bytes& operator=(const Bytes& rhs) = delete;
  65. std::pair<unsigned char*, int> detach() noexcept;
  66. ~Bytes(){ delete[] _data;}
  67. };
  68. using Super = std::pair<PyObject*, Type>;
  69. struct Slice {
  70. PyObject* start;
  71. PyObject* stop;
  72. PyObject* step;
  73. Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {}
  74. };
  75. struct PyObject{
  76. bool gc_enabled; // whether this object is managed by GC
  77. bool gc_marked; // whether this object is marked
  78. Type type;
  79. NameDict* _attr;
  80. bool is_attr_valid() const noexcept { return _attr != nullptr; }
  81. NameDict& attr() {
  82. PK_DEBUG_ASSERT(is_attr_valid())
  83. return *_attr;
  84. }
  85. PyObject* attr(StrName name) const {
  86. PK_DEBUG_ASSERT(is_attr_valid())
  87. return (*_attr)[name];
  88. }
  89. virtual void _obj_gc_mark() = 0;
  90. PyObject(Type type) : gc_enabled(true), gc_marked(false), type(type), _attr(nullptr) {}
  91. virtual ~PyObject(){
  92. if(_attr == nullptr) return;
  93. _attr->~NameDict();
  94. pool128_dealloc(_attr);
  95. }
  96. void _enable_instance_dict() {
  97. _attr = new(pool128_alloc<NameDict>()) NameDict();
  98. }
  99. void _enable_instance_dict(float lf){
  100. _attr = new(pool128_alloc<NameDict>()) NameDict(lf);
  101. }
  102. };
  103. const int kTpIntIndex = 2;
  104. const int kTpFloatIndex = 3;
  105. inline bool is_tagged(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) != 0b00; }
  106. inline bool is_small_int(PyObject* p) noexcept { return (PK_BITS(p) & 0b11) == 0b10; }
  107. inline bool is_heap_int(PyObject* p) noexcept { return !is_tagged(p) && p->type.index == kTpIntIndex; }
  108. inline bool is_float(PyObject* p) noexcept { return !is_tagged(p) && p->type.index == kTpFloatIndex; }
  109. inline bool is_int(PyObject* p) noexcept { return is_small_int(p) || is_heap_int(p); }
  110. inline bool is_type(PyObject* obj, Type type) {
  111. PK_DEBUG_ASSERT(obj != nullptr)
  112. return is_small_int(obj) ? type.index == kTpIntIndex : obj->type == type;
  113. }
  114. template <typename, typename=void> struct has_gc_marker : std::false_type {};
  115. template <typename T> struct has_gc_marker<T, std::void_t<decltype(&T::_gc_mark)>> : std::true_type {};
  116. template <typename T>
  117. struct Py_ final: PyObject {
  118. static_assert(!std::is_reference_v<T>, "T must not be a reference type. Are you using `PK_OBJ_GET(T&, ...)`?");
  119. T _value;
  120. void _obj_gc_mark() override {
  121. if constexpr (has_gc_marker<T>::value) {
  122. _value._gc_mark();
  123. }
  124. }
  125. template <typename... Args>
  126. Py_(Type type, Args&&... args) : PyObject(type), _value(std::forward<Args>(args)...) { }
  127. };
  128. struct MappingProxy{
  129. PyObject* obj;
  130. MappingProxy(PyObject* obj) : obj(obj) {}
  131. NameDict& attr() { return obj->attr(); }
  132. };
  133. void _gc_mark_namedict(NameDict*);
  134. StrName _type_name(VM* vm, Type type);
  135. template<typename T> T to_void_p(VM*, PyObject*);
  136. PyObject* from_void_p(VM*, void*);
  137. #define PK_OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
  138. #define PK_OBJ_MARK(obj) \
  139. if(!is_tagged(obj) && !(obj)->gc_marked) { \
  140. (obj)->gc_marked = true; \
  141. (obj)->_obj_gc_mark(); \
  142. if((obj)->is_attr_valid()) _gc_mark_namedict((obj)->_attr); \
  143. }
  144. #define VAR(x) py_var(vm, x)
  145. #define CAST(T, x) py_cast<T>(vm, x)
  146. #define _CAST(T, x) _py_cast<T>(vm, x)
  147. #define CAST_F(x) py_cast<f64>(vm, x)
  148. #define CAST_DEFAULT(T, x, default_value) (x != vm->None) ? py_cast<T>(vm, x) : (default_value)
  149. /*****************************************************************/
  150. template<>
  151. struct Py_<i64> final: PyObject {
  152. i64 _value;
  153. Py_(Type type, i64 val): PyObject(type), _value(val) {}
  154. void _obj_gc_mark() override {}
  155. };
  156. inline bool try_cast_int(PyObject* obj, i64* val) noexcept {
  157. if(is_small_int(obj)){
  158. *val = PK_BITS(obj) >> 2;
  159. return true;
  160. }else if(is_heap_int(obj)){
  161. *val = PK_OBJ_GET(i64, obj);
  162. return true;
  163. }else{
  164. return false;
  165. }
  166. }
  167. template<>
  168. struct Py_<List> final: PyObject {
  169. List _value;
  170. Py_(Type type, List&& val): PyObject(type), _value(std::move(val)) {}
  171. Py_(Type type, const List& val): PyObject(type), _value(val) {}
  172. void _obj_gc_mark() override {
  173. for(PyObject* obj: _value) PK_OBJ_MARK(obj);
  174. }
  175. };
  176. template<>
  177. struct Py_<Tuple> final: PyObject {
  178. Tuple _value;
  179. Py_(Type type, Tuple&& val): PyObject(type), _value(std::move(val)) {}
  180. Py_(Type type, const Tuple& val): PyObject(type), _value(val) {}
  181. void _obj_gc_mark() override {
  182. for(PyObject* obj: _value) PK_OBJ_MARK(obj);
  183. }
  184. };
  185. template<>
  186. struct Py_<MappingProxy> final: PyObject {
  187. MappingProxy _value;
  188. Py_(Type type, MappingProxy val): PyObject(type), _value(val) {}
  189. void _obj_gc_mark() override {
  190. PK_OBJ_MARK(_value.obj);
  191. }
  192. };
  193. template<>
  194. struct Py_<BoundMethod> final: PyObject {
  195. BoundMethod _value;
  196. Py_(Type type, BoundMethod val): PyObject(type), _value(val) {}
  197. void _obj_gc_mark() override {
  198. PK_OBJ_MARK(_value.self);
  199. PK_OBJ_MARK(_value.func);
  200. }
  201. };
  202. template<>
  203. struct Py_<StarWrapper> final: PyObject {
  204. StarWrapper _value;
  205. Py_(Type type, StarWrapper val): PyObject(type), _value(val) {}
  206. void _obj_gc_mark() override {
  207. PK_OBJ_MARK(_value.obj);
  208. }
  209. };
  210. template<>
  211. struct Py_<StaticMethod> final: PyObject {
  212. StaticMethod _value;
  213. Py_(Type type, StaticMethod val): PyObject(type), _value(val) {}
  214. void _obj_gc_mark() override {
  215. PK_OBJ_MARK(_value.func);
  216. }
  217. };
  218. template<>
  219. struct Py_<ClassMethod> final: PyObject {
  220. ClassMethod _value;
  221. Py_(Type type, ClassMethod val): PyObject(type), _value(val) {}
  222. void _obj_gc_mark() override {
  223. PK_OBJ_MARK(_value.func);
  224. }
  225. };
  226. template<>
  227. struct Py_<Property> final: PyObject {
  228. Property _value;
  229. Py_(Type type, Property val): PyObject(type), _value(val) {}
  230. void _obj_gc_mark() override {
  231. PK_OBJ_MARK(_value.getter);
  232. PK_OBJ_MARK(_value.setter);
  233. }
  234. };
  235. template<>
  236. struct Py_<Slice> final: PyObject {
  237. Slice _value;
  238. Py_(Type type, Slice val): PyObject(type), _value(val) {}
  239. void _obj_gc_mark() override {
  240. PK_OBJ_MARK(_value.start);
  241. PK_OBJ_MARK(_value.stop);
  242. PK_OBJ_MARK(_value.step);
  243. }
  244. };
  245. template<>
  246. struct Py_<Super> final: PyObject {
  247. Super _value;
  248. template<typename... Args>
  249. Py_(Type type, Args&&... args): PyObject(type), _value(std::forward<Args>(args)...) {}
  250. void _obj_gc_mark() override {
  251. PK_OBJ_MARK(_value.first);
  252. }
  253. };
  254. template<>
  255. struct Py_<DummyInstance> final: PyObject {
  256. Py_(Type type): PyObject(type) {
  257. _enable_instance_dict();
  258. }
  259. void _obj_gc_mark() override {}
  260. };
  261. template<>
  262. struct Py_<Type> final: PyObject {
  263. Type _value;
  264. Py_(Type type, Type val): PyObject(type), _value(val) {
  265. _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR);
  266. }
  267. void _obj_gc_mark() override {}
  268. };
  269. template<>
  270. struct Py_<DummyModule> final: PyObject {
  271. Py_(Type type): PyObject(type) {
  272. _enable_instance_dict(PK_TYPE_ATTR_LOAD_FACTOR);
  273. }
  274. void _obj_gc_mark() override {}
  275. };
  276. extern PyObject* const PY_NULL;
  277. extern PyObject* const PY_OP_CALL;
  278. extern PyObject* const PY_OP_YIELD;
  279. } // namespace pkpy