obj.h 12 KB

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