obj.h 9.8 KB

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