obj.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. #pragma once
  2. #include "common.h"
  3. #include "namedict.h"
  4. #include "tuplelist.h"
  5. namespace pkpy {
  6. struct CodeObject;
  7. struct Frame;
  8. struct Function;
  9. class VM;
  10. typedef PyObject* (*NativeFuncC)(VM*, ArgsView);
  11. typedef int (*LuaStyleFuncC)(VM*);
  12. struct NativeFunc {
  13. NativeFuncC f;
  14. int argc; // DONOT include self
  15. bool method;
  16. // this is designed for lua style C bindings
  17. // access it via `CAST(NativeFunc&, args[-2])._lua_f`
  18. LuaStyleFuncC _lua_f;
  19. NativeFunc(NativeFuncC f, int argc, bool method) : f(f), argc(argc), method(method), _lua_f(nullptr) {}
  20. PyObject* operator()(VM* vm, ArgsView args) const;
  21. };
  22. typedef shared_ptr<CodeObject> CodeObject_;
  23. struct FuncDecl {
  24. struct KwArg {
  25. int key; // index in co->varnames
  26. PyObject* value; // default value
  27. };
  28. CodeObject_ code; // code object of this function
  29. pod_vector<int> args; // indices in co->varnames
  30. int starred_arg = -1; // index in co->varnames, -1 if no *arg
  31. pod_vector<KwArg> kwargs; // indices in co->varnames
  32. bool nested = false; // whether this function is nested
  33. void _gc_mark() const;
  34. };
  35. using FuncDecl_ = shared_ptr<FuncDecl>;
  36. struct Function{
  37. FuncDecl_ decl;
  38. bool is_simple;
  39. int argc; // cached argc
  40. PyObject* _module;
  41. NameDict_ _closure;
  42. };
  43. struct BoundMethod {
  44. PyObject* self;
  45. PyObject* func;
  46. BoundMethod(PyObject* self, PyObject* func) : self(self), func(func) {}
  47. bool operator==(const BoundMethod& rhs) const noexcept {
  48. return self == rhs.self && func == rhs.func;
  49. }
  50. bool operator!=(const BoundMethod& rhs) const noexcept {
  51. return self != rhs.self || func != rhs.func;
  52. }
  53. };
  54. struct Range {
  55. i64 start = 0;
  56. i64 stop = -1;
  57. i64 step = 1;
  58. };
  59. struct Bytes{
  60. std::vector<char> _data;
  61. bool _ok;
  62. int size() const noexcept { return _data.size(); }
  63. int operator[](int i) const noexcept { return (int)(uint8_t)_data[i]; }
  64. const char* data() const noexcept { return _data.data(); }
  65. bool operator==(const Bytes& rhs) const noexcept {
  66. return _data == rhs._data;
  67. }
  68. bool operator!=(const Bytes& rhs) const noexcept {
  69. return _data != rhs._data;
  70. }
  71. std::string str() const noexcept { return std::string(_data.begin(), _data.end()); }
  72. Bytes() : _data(), _ok(false) {}
  73. Bytes(std::vector<char>&& data) : _data(std::move(data)), _ok(true) {}
  74. Bytes(const std::string& data) : _data(data.begin(), data.end()), _ok(true) {}
  75. operator bool() const noexcept { return _ok; }
  76. };
  77. using Super = std::pair<PyObject*, Type>;
  78. struct Slice {
  79. PyObject* start;
  80. PyObject* stop;
  81. PyObject* step;
  82. Slice(PyObject* start, PyObject* stop, PyObject* step) : start(start), stop(stop), step(step) {}
  83. };
  84. class BaseIter {
  85. protected:
  86. VM* vm;
  87. public:
  88. BaseIter(VM* vm) : vm(vm) {}
  89. virtual PyObject* next() = 0;
  90. virtual ~BaseIter() = default;
  91. };
  92. struct GCHeader {
  93. bool enabled; // whether this object is managed by GC
  94. bool marked; // whether this object is marked
  95. GCHeader() : enabled(true), marked(false) {}
  96. };
  97. struct PyObject{
  98. GCHeader gc;
  99. Type type;
  100. NameDict* _attr;
  101. bool is_attr_valid() const noexcept { return _attr != nullptr; }
  102. NameDict& attr() noexcept { return *_attr; }
  103. PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
  104. virtual void* value() = 0;
  105. virtual void _obj_gc_mark() = 0;
  106. PyObject(Type type) : type(type), _attr(nullptr) {}
  107. virtual ~PyObject() {
  108. if(_attr == nullptr) return;
  109. _attr->~NameDict();
  110. pool64.dealloc(_attr);
  111. }
  112. void enable_instance_dict(float lf=kInstAttrLoadFactor) noexcept {
  113. _attr = new(pool64.alloc<NameDict>()) NameDict(lf);
  114. }
  115. };
  116. template <typename, typename=void> struct has_gc_marker : std::false_type {};
  117. template <typename T> struct has_gc_marker<T, std::void_t<decltype(&T::_gc_mark)>> : std::true_type {};
  118. template <typename T>
  119. struct Py_ final: PyObject {
  120. T _value;
  121. void* value() override { return &_value; }
  122. void _obj_gc_mark() override {
  123. if constexpr (has_gc_marker<T>::value) {
  124. _value._gc_mark();
  125. }
  126. }
  127. Py_(Type type, const T& value) : PyObject(type), _value(value) {}
  128. Py_(Type type, T&& value) : PyObject(type), _value(std::move(value)) {}
  129. };
  130. struct MappingProxy{
  131. PyObject* obj;
  132. MappingProxy(PyObject* obj) : obj(obj) {}
  133. NameDict& attr() noexcept { return obj->attr(); }
  134. };
  135. #define OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
  136. // #define OBJ_GET(T, obj) (*reinterpret_cast<T*>((obj)->value()))
  137. #define OBJ_MARK(obj) \
  138. if(!is_tagged(obj) && !(obj)->gc.marked) { \
  139. (obj)->gc.marked = true; \
  140. (obj)->_obj_gc_mark(); \
  141. if((obj)->is_attr_valid()) gc_mark_namedict((obj)->attr()); \
  142. }
  143. inline void gc_mark_namedict(NameDict& t){
  144. if(t.size() == 0) return;
  145. for(uint16_t i=0; i<t._capacity; i++){
  146. if(t._items[i].first.empty()) continue;
  147. OBJ_MARK(t._items[i].second);
  148. }
  149. }
  150. Str obj_type_name(VM* vm, Type type);
  151. #if DEBUG_NO_BUILTIN_MODULES
  152. #define OBJ_NAME(obj) Str("<?>")
  153. #else
  154. #define OBJ_NAME(obj) OBJ_GET(Str, vm->getattr(obj, __name__))
  155. #endif
  156. const int kTpIntIndex = 2;
  157. const int kTpFloatIndex = 3;
  158. inline bool is_type(PyObject* obj, Type type) {
  159. #if DEBUG_EXTRA_CHECK
  160. if(obj == nullptr) throw std::runtime_error("is_type() called with nullptr");
  161. if(is_special(obj)) throw std::runtime_error("is_type() called with special object");
  162. #endif
  163. switch(type.index){
  164. case kTpIntIndex: return is_int(obj);
  165. case kTpFloatIndex: return is_float(obj);
  166. default: return !is_tagged(obj) && obj->type == type;
  167. }
  168. }
  169. inline bool is_non_tagged_type(PyObject* obj, Type type) {
  170. #if DEBUG_EXTRA_CHECK
  171. if(obj == nullptr) throw std::runtime_error("is_non_tagged_type() called with nullptr");
  172. if(is_special(obj)) throw std::runtime_error("is_non_tagged_type() called with special object");
  173. #endif
  174. return !is_tagged(obj) && obj->type == type;
  175. }
  176. union BitsCvt {
  177. i64 _int;
  178. f64 _float;
  179. BitsCvt(i64 val) : _int(val) {}
  180. BitsCvt(f64 val) : _float(val) {}
  181. };
  182. template <typename, typename=void> struct is_py_class : std::false_type {};
  183. template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {};
  184. template<typename T> void _check_py_class(VM*, PyObject*);
  185. template<typename T> T py_pointer_cast(VM*, PyObject*);
  186. template<typename __T>
  187. __T py_cast(VM* vm, PyObject* obj) {
  188. using T = std::decay_t<__T>;
  189. if constexpr(std::is_pointer_v<T>){
  190. return py_pointer_cast<T>(vm, obj);
  191. }else if constexpr(is_py_class<T>::value){
  192. _check_py_class<T>(vm, obj);
  193. return OBJ_GET(T, obj);
  194. }else {
  195. return Discarded();
  196. }
  197. }
  198. template<typename __T>
  199. __T _py_cast(VM* vm, PyObject* obj) {
  200. using T = std::decay_t<__T>;
  201. if constexpr(std::is_pointer_v<__T>){
  202. return py_pointer_cast<__T>(vm, obj);
  203. }else if constexpr(is_py_class<T>::value){
  204. return OBJ_GET(T, obj);
  205. }else{
  206. return Discarded();
  207. }
  208. }
  209. #define VAR(x) py_var(vm, x)
  210. #define CAST(T, x) py_cast<T>(vm, x)
  211. #define _CAST(T, x) _py_cast<T>(vm, x)
  212. /*****************************************************************/
  213. template<>
  214. struct Py_<List> final: PyObject {
  215. List _value;
  216. void* value() override { return &_value; }
  217. Py_(Type type, List&& val): PyObject(type), _value(std::move(val)) {}
  218. Py_(Type type, const List& val): PyObject(type), _value(val) {}
  219. void _obj_gc_mark() override {
  220. for(PyObject* obj: _value) OBJ_MARK(obj);
  221. }
  222. };
  223. template<>
  224. struct Py_<Tuple> final: PyObject {
  225. Tuple _value;
  226. void* value() override { return &_value; }
  227. Py_(Type type, Tuple&& val): PyObject(type), _value(std::move(val)) {}
  228. Py_(Type type, const Tuple& val): PyObject(type), _value(val) {}
  229. void _obj_gc_mark() override {
  230. for(PyObject* obj: _value) OBJ_MARK(obj);
  231. }
  232. };
  233. template<>
  234. struct Py_<MappingProxy> final: PyObject {
  235. MappingProxy _value;
  236. void* value() override { return &_value; }
  237. Py_(Type type, MappingProxy val): PyObject(type), _value(val) {}
  238. void _obj_gc_mark() override {
  239. OBJ_MARK(_value.obj);
  240. }
  241. };
  242. template<>
  243. struct Py_<BoundMethod> final: PyObject {
  244. BoundMethod _value;
  245. void* value() override { return &_value; }
  246. Py_(Type type, BoundMethod val): PyObject(type), _value(val) {}
  247. void _obj_gc_mark() override {
  248. OBJ_MARK(_value.self);
  249. OBJ_MARK(_value.func);
  250. }
  251. };
  252. template<>
  253. struct Py_<Slice> final: PyObject {
  254. Slice _value;
  255. void* value() override { return &_value; }
  256. Py_(Type type, Slice val): PyObject(type), _value(val) {}
  257. void _obj_gc_mark() override {
  258. OBJ_MARK(_value.start);
  259. OBJ_MARK(_value.stop);
  260. OBJ_MARK(_value.step);
  261. }
  262. };
  263. template<>
  264. struct Py_<Function> final: PyObject {
  265. Function _value;
  266. void* value() override { return &_value; }
  267. Py_(Type type, Function val): PyObject(type), _value(val) {
  268. enable_instance_dict();
  269. }
  270. void _obj_gc_mark() override {
  271. _value.decl->_gc_mark();
  272. if(_value._module != nullptr) OBJ_MARK(_value._module);
  273. if(_value._closure != nullptr) gc_mark_namedict(*_value._closure);
  274. }
  275. };
  276. template<>
  277. struct Py_<NativeFunc> final: PyObject {
  278. NativeFunc _value;
  279. void* value() override { return &_value; }
  280. Py_(Type type, NativeFunc val): PyObject(type), _value(val) {
  281. enable_instance_dict();
  282. }
  283. void _obj_gc_mark() override {}
  284. };
  285. template<>
  286. struct Py_<Super> final: PyObject {
  287. Super _value;
  288. void* value() override { return &_value; }
  289. Py_(Type type, Super val): PyObject(type), _value(val) {}
  290. void _obj_gc_mark() override {
  291. OBJ_MARK(_value.first);
  292. }
  293. };
  294. template<>
  295. struct Py_<DummyInstance> final: PyObject {
  296. void* value() override { return nullptr; }
  297. Py_(Type type, DummyInstance val): PyObject(type) {
  298. enable_instance_dict();
  299. }
  300. void _obj_gc_mark() override {}
  301. };
  302. template<>
  303. struct Py_<Type> final: PyObject {
  304. Type _value;
  305. void* value() override { return &_value; }
  306. Py_(Type type, Type val): PyObject(type), _value(val) {
  307. enable_instance_dict(kTypeAttrLoadFactor);
  308. }
  309. void _obj_gc_mark() override {}
  310. };
  311. template<>
  312. struct Py_<DummyModule> final: PyObject {
  313. void* value() override { return nullptr; }
  314. Py_(Type type, DummyModule val): PyObject(type) {
  315. enable_instance_dict(kTypeAttrLoadFactor);
  316. }
  317. void _obj_gc_mark() override {}
  318. };
  319. } // namespace pkpy