obj.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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 BaseRef;
  9. class VM;
  10. typedef std::function<PyObject*(VM*, Args&)> NativeFuncRaw;
  11. typedef shared_ptr<CodeObject> CodeObject_;
  12. typedef shared_ptr<NameDict> NameDict_;
  13. struct NativeFunc {
  14. NativeFuncRaw f;
  15. int argc; // DONOT include self
  16. bool method;
  17. NativeFunc(NativeFuncRaw f, int argc, bool method) : f(f), argc(argc), method(method) {}
  18. PyObject* operator()(VM* vm, Args& args) const;
  19. };
  20. struct FuncDecl {
  21. StrName name;
  22. CodeObject_ code;
  23. std::vector<StrName> args;
  24. StrName starred_arg; // empty if no *arg
  25. NameDict kwargs; // empty if no k=v
  26. std::vector<StrName> kwargs_order;
  27. bool has_name(StrName val) const {
  28. bool _0 = std::find(args.begin(), args.end(), val) != args.end();
  29. bool _1 = starred_arg == val;
  30. bool _2 = kwargs.contains(val);
  31. return _0 || _1 || _2;
  32. }
  33. void _gc_mark() const;
  34. };
  35. using FuncDecl_ = shared_ptr<FuncDecl>;
  36. struct Function{
  37. FuncDecl_ decl;
  38. PyObject* _module;
  39. NameDict_ _closure;
  40. };
  41. struct BoundMethod {
  42. PyObject* obj;
  43. PyObject* method;
  44. BoundMethod(PyObject* obj, PyObject* method) : obj(obj), method(method) {}
  45. };
  46. struct Range {
  47. i64 start = 0;
  48. i64 stop = -1;
  49. i64 step = 1;
  50. };
  51. struct StarWrapper {
  52. PyObject* obj;
  53. StarWrapper(PyObject* obj): obj(obj) {}
  54. };
  55. using Super = std::pair<PyObject*, Type>;
  56. // TODO: re-examine the design of Slice
  57. struct Slice {
  58. int start = 0;
  59. int stop = 0x7fffffff;
  60. int step = 1;
  61. void normalize(int len){
  62. if(start < 0) start += len;
  63. if(stop < 0) stop += len;
  64. if(start < 0) start = 0;
  65. if(stop > len) stop = len;
  66. if(stop < start) stop = start;
  67. }
  68. };
  69. class BaseIter {
  70. protected:
  71. VM* vm;
  72. public:
  73. BaseIter(VM* vm) : vm(vm) {}
  74. virtual void _gc_mark() const {}
  75. virtual PyObject* next() = 0;
  76. virtual ~BaseIter() = default;
  77. };
  78. struct GCHeader {
  79. bool enabled; // whether this object is managed by GC
  80. bool marked; // whether this object is marked
  81. GCHeader() : enabled(true), marked(false) {}
  82. };
  83. struct PyObject {
  84. GCHeader gc;
  85. Type type;
  86. NameDict* _attr;
  87. bool is_attr_valid() const noexcept { return _attr != nullptr; }
  88. NameDict& attr() noexcept { return *_attr; }
  89. PyObject* attr(StrName name) const noexcept { return (*_attr)[name]; }
  90. virtual void* value() = 0;
  91. virtual void _obj_gc_mark() = 0;
  92. PyObject(Type type) : type(type) {}
  93. virtual ~PyObject() { delete _attr; }
  94. };
  95. template<typename T>
  96. void _gc_mark(T& t);
  97. template <typename T>
  98. struct Py_ : PyObject {
  99. T _value;
  100. Py_(Type type, const T& val): PyObject(type), _value(val) { _init(); }
  101. Py_(Type type, T&& val): PyObject(type), _value(std::move(val)) { _init(); }
  102. void _init() noexcept {
  103. if constexpr (std::is_same_v<T, Type> || std::is_same_v<T, DummyModule>) {
  104. _attr = new NameDict(8, kTypeAttrLoadFactor);
  105. }else if constexpr(std::is_same_v<T, DummyInstance>){
  106. _attr = new NameDict(8, kInstAttrLoadFactor);
  107. }else if constexpr(std::is_same_v<T, Function> || std::is_same_v<T, NativeFunc>){
  108. _attr = new NameDict(8, kInstAttrLoadFactor);
  109. }else{
  110. _attr = nullptr;
  111. }
  112. }
  113. void* value() override { return &_value; }
  114. void _obj_gc_mark() override {
  115. if(gc.marked) return;
  116. gc.marked = true;
  117. if(_attr != nullptr) _attr->_gc_mark();
  118. pkpy::_gc_mark<T>(_value); // handle PyObject* inside _value `T`
  119. }
  120. };
  121. #define OBJ_GET(T, obj) (((Py_<T>*)(obj))->_value)
  122. #define OBJ_MARK(obj) if(!is_tagged(obj)) obj->_obj_gc_mark()
  123. Str obj_type_name(VM* vm, Type type);
  124. #if DEBUG_NO_BUILTIN_MODULES
  125. #define OBJ_NAME(obj) Str("<?>")
  126. #else
  127. #define OBJ_NAME(obj) OBJ_GET(Str, vm->getattr(obj, __name__))
  128. #endif
  129. const int kTpIntIndex = 2;
  130. const int kTpFloatIndex = 3;
  131. inline bool is_type(PyObject* obj, Type type) noexcept {
  132. switch(type.index){
  133. case kTpIntIndex: return is_int(obj);
  134. case kTpFloatIndex: return is_float(obj);
  135. default: return !is_tagged(obj) && obj->type == type;
  136. }
  137. }
  138. #define PY_CLASS(T, mod, name) \
  139. static Type _type(VM* vm) { \
  140. static const StrName __x0(#mod); \
  141. static const StrName __x1(#name); \
  142. return OBJ_GET(Type, vm->_modules[__x0]->attr(__x1)); \
  143. } \
  144. static PyObject* register_class(VM* vm, PyObject* mod) { \
  145. PyObject* type = vm->new_type_object(mod, #name, vm->tp_object); \
  146. if(OBJ_NAME(mod) != #mod) UNREACHABLE(); \
  147. T::_register(vm, mod, type); \
  148. type->attr()._try_perfect_rehash(); \
  149. return type; \
  150. }
  151. union BitsCvt {
  152. i64 _int;
  153. f64 _float;
  154. BitsCvt(i64 val) : _int(val) {}
  155. BitsCvt(f64 val) : _float(val) {}
  156. };
  157. template <typename, typename=void> struct is_py_class : std::false_type {};
  158. template <typename T> struct is_py_class<T, std::void_t<decltype(T::_type)>> : std::true_type {};
  159. template<typename T> void _check_py_class(VM*, PyObject*);
  160. template<typename T> T py_pointer_cast(VM*, PyObject*);
  161. template<typename T> T py_value_cast(VM*, PyObject*);
  162. struct Discarded { };
  163. template<typename __T>
  164. __T py_cast(VM* vm, PyObject* obj) {
  165. using T = std::decay_t<__T>;
  166. if constexpr(std::is_pointer_v<T>){
  167. return py_pointer_cast<T>(vm, obj);
  168. }else if constexpr(is_py_class<T>::value){
  169. _check_py_class<T>(vm, obj);
  170. return OBJ_GET(T, obj);
  171. }else if constexpr(std::is_pod_v<T>){
  172. return py_value_cast<T>(vm, obj);
  173. }else{
  174. return Discarded();
  175. }
  176. }
  177. template<typename __T>
  178. __T _py_cast(VM* vm, PyObject* obj) {
  179. using T = std::decay_t<__T>;
  180. if constexpr(std::is_pointer_v<__T>){
  181. return py_pointer_cast<__T>(vm, obj);
  182. }else if constexpr(is_py_class<T>::value){
  183. return OBJ_GET(T, obj);
  184. }else{
  185. return Discarded();
  186. }
  187. }
  188. #define VAR(x) py_var(vm, x)
  189. #define VAR_T(T, ...) vm->heap.gcnew<T>(T::_type(vm), T(__VA_ARGS__))
  190. #define CAST(T, x) py_cast<T>(vm, x)
  191. #define _CAST(T, x) _py_cast<T>(vm, x)
  192. } // namespace pkpy