obj.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. Property(PyObject* getter, PyObject* setter) : getter(getter), setter(setter) {}
  28. };
  29. struct Range {
  30. i64 start = 0;
  31. i64 stop = -1;
  32. i64 step = 1;
  33. };
  34. struct StarWrapper{
  35. int level; // either 1 or 2
  36. PyObject* obj;
  37. StarWrapper(int level, PyObject* obj) : level(level), obj(obj) {}
  38. };
  39. struct Bytes{
  40. std::vector<char> _data;
  41. bool _ok;
  42. int size() const noexcept { return _data.size(); }
  43. int operator[](int i) const noexcept { return (int)(uint8_t)_data[i]; }
  44. const char* data() const noexcept { return _data.data(); }
  45. bool operator==(const Bytes& rhs) const noexcept {
  46. return _data == rhs._data;
  47. }
  48. bool operator!=(const Bytes& rhs) const noexcept {
  49. return _data != rhs._data;
  50. }
  51. std::string str() const noexcept { return std::string(_data.begin(), _data.end()); }
  52. Bytes() : _data(), _ok(false) {}
  53. Bytes(std::vector<char>&& data) : _data(std::move(data)), _ok(true) {}
  54. Bytes(const std::string& data) : _data(data.begin(), data.end()), _ok(true) {}
  55. operator bool() const noexcept { return _ok; }
  56. };
  57. using Super = std::pair<PyObject*, Type>;
  58. struct Slice {
  59. PyObject* start;
  60. PyObject* stop;
  61. PyObject* step;
  62. Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {}
  63. };
  64. struct GCHeader {
  65. bool enabled; // whether this object is managed by GC
  66. bool marked; // whether this object is marked
  67. GCHeader() : enabled(true), marked(false) {}
  68. };
  69. struct PyObject{
  70. GCHeader gc;
  71. Type type;
  72. NameDict* _attr;
  73. bool is_attr_valid() const noexcept { return _attr != nullptr; }
  74. NameDict& attr() noexcept { return *_attr; }
  75. PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
  76. virtual void _obj_gc_mark() = 0;
  77. PyObject(Type type) : type(type), _attr(nullptr) {}
  78. virtual ~PyObject();
  79. void enable_instance_dict(float lf=kInstAttrLoadFactor) {
  80. _attr = new(pool64.alloc<NameDict>()) NameDict(lf);
  81. }
  82. };
  83. template <typename, typename=void> struct has_gc_marker : std::false_type {};
  84. template <typename T> struct has_gc_marker<T, std::void_t<decltype(&T::_gc_mark)>> : std::true_type {};
  85. template <typename T>
  86. struct Py_ final: PyObject {
  87. T _value;
  88. void _obj_gc_mark() override {
  89. if constexpr (has_gc_marker<T>::value) {
  90. _value._gc_mark();
  91. }
  92. }
  93. Py_(Type type, const T& value) : PyObject(type), _value(value) {}
  94. Py_(Type type, T&& value) : PyObject(type), _value(std::move(value)) {}
  95. };
  96. struct MappingProxy{
  97. PyObject* obj;
  98. MappingProxy(PyObject* obj) : obj(obj) {}
  99. NameDict& attr() noexcept { return obj->attr(); }
  100. };
  101. #define PK_OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
  102. #define PK_OBJ_MARK(obj) \
  103. if(!is_tagged(obj) && !(obj)->gc.marked) { \
  104. (obj)->gc.marked = true; \
  105. (obj)->_obj_gc_mark(); \
  106. if((obj)->is_attr_valid()) gc_mark_namedict((obj)->attr()); \
  107. }
  108. inline void gc_mark_namedict(NameDict& t){
  109. if(t.size() == 0) return;
  110. for(uint16_t i=0; i<t._capacity; i++){
  111. if(t._items[i].first.empty()) continue;
  112. PK_OBJ_MARK(t._items[i].second);
  113. }
  114. }
  115. Str obj_type_name(VM* vm, Type type);
  116. #if PK_DEBUG_NO_BUILTINS
  117. #define OBJ_NAME(obj) Str("<?>")
  118. #else
  119. DEF_SNAME(__name__);
  120. #define OBJ_NAME(obj) PK_OBJ_GET(Str, vm->getattr(obj, __name__))
  121. #endif
  122. const int kTpIntIndex = 2;
  123. const int kTpFloatIndex = 3;
  124. inline bool is_type(PyObject* obj, Type type) {
  125. #if PK_DEBUG_EXTRA_CHECK
  126. if(obj == nullptr) throw std::runtime_error("is_type() called with nullptr");
  127. if(is_special(obj)) throw std::runtime_error("is_type() called with special object");
  128. #endif
  129. switch(type.index){
  130. case kTpIntIndex: return is_int(obj);
  131. case kTpFloatIndex: return is_float(obj);
  132. default: return !is_tagged(obj) && obj->type == type;
  133. }
  134. }
  135. inline bool is_non_tagged_type(PyObject* obj, Type type) {
  136. #if PK_DEBUG_EXTRA_CHECK
  137. if(obj == nullptr) throw std::runtime_error("is_non_tagged_type() called with nullptr");
  138. if(is_special(obj)) throw std::runtime_error("is_non_tagged_type() called with special object");
  139. #endif
  140. return !is_tagged(obj) && obj->type == type;
  141. }
  142. union BitsCvt {
  143. i64 _int;
  144. f64 _float;
  145. BitsCvt(i64 val) : _int(val) {}
  146. BitsCvt(f64 val) : _float(val) {}
  147. };
  148. template <typename, typename=void> struct is_py_class : std::false_type {};
  149. template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {};
  150. template<typename T> T to_void_p(VM*, PyObject*);
  151. template<typename T> T to_c99_struct(VM*, PyObject*);
  152. template<typename __T>
  153. __T py_cast(VM* vm, PyObject* obj) {
  154. using T = std::decay_t<__T>;
  155. if constexpr(std::is_enum_v<T>){
  156. return (__T)py_cast<i64>(vm, obj);
  157. }else if constexpr(std::is_pointer_v<T>){
  158. return to_void_p<T>(vm, obj);
  159. }else if constexpr(is_py_class<T>::value){
  160. T::_check_type(vm, obj);
  161. return PK_OBJ_GET(T, obj);
  162. }else if constexpr(std::is_pod_v<T>){
  163. return to_c99_struct<T>(vm, obj);
  164. }else {
  165. return Discarded();
  166. }
  167. }
  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. return PK_OBJ_GET(T, obj);
  177. }else if constexpr(std::is_pod_v<T>){
  178. return to_c99_struct<T>(vm, obj);
  179. }else {
  180. return Discarded();
  181. }
  182. }
  183. #define VAR(x) py_var(vm, x)
  184. #define CAST(T, x) py_cast<T>(vm, x)
  185. #define _CAST(T, x) _py_cast<T>(vm, x)
  186. #define CAST_F(x) vm->num_to_float(x)
  187. #define CAST_DEFAULT(T, x, default_value) (x != vm->None) ? py_cast<T>(vm, x) : (default_value)
  188. /*****************************************************************/
  189. template<>
  190. struct Py_<List> final: PyObject {
  191. List _value;
  192. Py_(Type type, List&& val): PyObject(type), _value(std::move(val)) {}
  193. Py_(Type type, const List& val): PyObject(type), _value(val) {}
  194. void _obj_gc_mark() override {
  195. for(PyObject* obj: _value) PK_OBJ_MARK(obj);
  196. }
  197. };
  198. template<>
  199. struct Py_<Tuple> final: PyObject {
  200. Tuple _value;
  201. Py_(Type type, Tuple&& val): PyObject(type), _value(std::move(val)) {}
  202. Py_(Type type, const Tuple& val): PyObject(type), _value(val) {}
  203. void _obj_gc_mark() override {
  204. for(PyObject* obj: _value) PK_OBJ_MARK(obj);
  205. }
  206. };
  207. template<>
  208. struct Py_<MappingProxy> final: PyObject {
  209. MappingProxy _value;
  210. Py_(Type type, MappingProxy val): PyObject(type), _value(val) {}
  211. void _obj_gc_mark() override {
  212. PK_OBJ_MARK(_value.obj);
  213. }
  214. };
  215. template<>
  216. struct Py_<BoundMethod> final: PyObject {
  217. BoundMethod _value;
  218. Py_(Type type, BoundMethod val): PyObject(type), _value(val) {}
  219. void _obj_gc_mark() override {
  220. PK_OBJ_MARK(_value.self);
  221. PK_OBJ_MARK(_value.func);
  222. }
  223. };
  224. template<>
  225. struct Py_<StarWrapper> final: PyObject {
  226. StarWrapper _value;
  227. Py_(Type type, StarWrapper val): PyObject(type), _value(val) {}
  228. void _obj_gc_mark() override {
  229. PK_OBJ_MARK(_value.obj);
  230. }
  231. };
  232. template<>
  233. struct Py_<Property> final: PyObject {
  234. Property _value;
  235. Py_(Type type, Property val): PyObject(type), _value(val) {}
  236. void _obj_gc_mark() override {
  237. PK_OBJ_MARK(_value.getter);
  238. PK_OBJ_MARK(_value.setter);
  239. }
  240. };
  241. template<>
  242. struct Py_<Slice> final: PyObject {
  243. Slice _value;
  244. Py_(Type type, Slice val): PyObject(type), _value(val) {}
  245. void _obj_gc_mark() override {
  246. PK_OBJ_MARK(_value.start);
  247. PK_OBJ_MARK(_value.stop);
  248. PK_OBJ_MARK(_value.step);
  249. }
  250. };
  251. template<>
  252. struct Py_<Super> final: PyObject {
  253. Super _value;
  254. Py_(Type type, Super val): PyObject(type), _value(val) {}
  255. void _obj_gc_mark() override {
  256. PK_OBJ_MARK(_value.first);
  257. }
  258. };
  259. template<>
  260. struct Py_<DummyInstance> final: PyObject {
  261. Py_(Type type, DummyInstance val): PyObject(type) {
  262. PK_UNUSED(val);
  263. enable_instance_dict();
  264. }
  265. void _obj_gc_mark() override {}
  266. };
  267. template<>
  268. struct Py_<Type> final: PyObject {
  269. Type _value;
  270. Py_(Type type, Type val): PyObject(type), _value(val) {
  271. enable_instance_dict(kTypeAttrLoadFactor);
  272. }
  273. void _obj_gc_mark() override {}
  274. };
  275. template<>
  276. struct Py_<DummyModule> final: PyObject {
  277. Py_(Type type, DummyModule val): PyObject(type) {
  278. PK_UNUSED(val);
  279. enable_instance_dict(kTypeAttrLoadFactor);
  280. }
  281. void _obj_gc_mark() override {}
  282. };
  283. } // namespace pkpy