obj.h 12 KB

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