1
0

obj.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #pragma once
  2. #include "namedict.h"
  3. #include "tuplelist.h"
  4. struct CodeObject;
  5. struct Frame;
  6. struct BaseRef;
  7. class VM;
  8. typedef std::function<PyVar(VM*, pkpy::Args&)> NativeFuncRaw;
  9. typedef pkpy::shared_ptr<CodeObject> CodeObject_;
  10. namespace pkpy{
  11. struct NativeFunc {
  12. NativeFuncRaw f;
  13. int argc; // DONOT include self
  14. bool method;
  15. NativeFunc(NativeFuncRaw f, int argc, bool method) : f(f), argc(argc), method(method) {}
  16. inline PyVar operator()(VM* vm, pkpy::Args& args) const;
  17. };
  18. struct Function {
  19. Str name;
  20. CodeObject_ code;
  21. std::vector<StrName> args;
  22. StrName starred_arg; // empty if no *arg
  23. pkpy::NameDict kwargs; // empty if no k=v
  24. std::vector<StrName> kwargs_order;
  25. // runtime settings
  26. PyVar _module;
  27. pkpy::shared_ptr<pkpy::NameDict> _closure;
  28. bool has_name(const Str& val) const {
  29. bool _0 = std::find(args.begin(), args.end(), val) != args.end();
  30. bool _1 = starred_arg == val;
  31. bool _2 = kwargs.contains(val);
  32. return _0 || _1 || _2;
  33. }
  34. };
  35. struct BoundMethod {
  36. PyVar obj;
  37. PyVar method;
  38. };
  39. struct Range {
  40. i64 start = 0;
  41. i64 stop = -1;
  42. i64 step = 1;
  43. };
  44. struct Slice {
  45. int start = 0;
  46. int stop = 0x7fffffff;
  47. void normalize(int len){
  48. if(start < 0) start += len;
  49. if(stop < 0) stop += len;
  50. if(start < 0) start = 0;
  51. if(stop > len) stop = len;
  52. if(stop < start) stop = start;
  53. }
  54. };
  55. }
  56. class BaseIter {
  57. protected:
  58. VM* vm;
  59. PyVar _ref; // keep a reference to the object so it will not be deleted while iterating
  60. public:
  61. virtual PyVar next() = 0;
  62. PyVarRef loop_var;
  63. BaseIter(VM* vm, PyVar _ref) : vm(vm), _ref(_ref) {}
  64. virtual ~BaseIter() = default;
  65. };
  66. struct PyObject {
  67. Type type;
  68. pkpy::NameDict* _attr;
  69. inline bool is_attr_valid() const noexcept { return _attr != nullptr; }
  70. inline pkpy::NameDict& attr() noexcept { return *_attr; }
  71. inline PyVar& attr(StrName name) noexcept { return (*_attr)[name]; }
  72. virtual void* value() = 0;
  73. PyObject(Type type) : type(type) {}
  74. virtual ~PyObject() { delete _attr; }
  75. };
  76. template <typename T>
  77. struct Py_ : PyObject {
  78. T _value;
  79. Py_(Type type, const T& val): PyObject(type), _value(val) { _init(); }
  80. Py_(Type type, T&& val): PyObject(type), _value(std::move(val)) { _init(); }
  81. inline void _init() noexcept {
  82. if constexpr (std::is_same_v<T, Type> || std::is_same_v<T, DummyModule>) {
  83. _attr = new pkpy::NameDict(8, kTypeAttrLoadFactor);
  84. }else if constexpr(std::is_same_v<T, DummyInstance>){
  85. _attr = new pkpy::NameDict(4, kInstAttrLoadFactor);
  86. }else{
  87. _attr = nullptr;
  88. }
  89. }
  90. void* value() override { return &_value; }
  91. };
  92. #define OBJ_GET(T, obj) (((Py_<T>*)((obj).get()))->_value)
  93. #define OBJ_NAME(obj) OBJ_GET(Str, (obj)->attr(__name__))
  94. const int kTpIntIndex = 2;
  95. const int kTpFloatIndex = 3;
  96. inline bool is_type(const PyVar& obj, Type type) noexcept {
  97. switch(type.index){
  98. case kTpIntIndex: return obj.is_tag_01();
  99. case kTpFloatIndex: return obj.is_tag_10();
  100. default: return !obj.is_tagged() && obj->type == type;
  101. }
  102. }
  103. inline bool is_both_int_or_float(const PyVar& a, const PyVar& b) noexcept {
  104. return ((a.bits | b.bits) & 0b11) != 0b00;
  105. }
  106. inline bool is_both_int(const PyVar& a, const PyVar& b) noexcept {
  107. return (a.bits & b.bits & 0b11) == 0b01;
  108. }
  109. inline bool is_int(const PyVar& obj) noexcept {
  110. return obj.is_tag_01();
  111. }
  112. inline bool is_float(const PyVar& obj) noexcept {
  113. return obj.is_tag_10();
  114. }
  115. #define PY_CLASS(mod, name) \
  116. inline static Type _type(VM* vm) { return OBJ_GET(Type, vm->_modules[#mod]->attr(#name)); } \
  117. inline static const char* _mod() { return #mod; } \
  118. inline static const char* _name() { return #name; }
  119. union __8B {
  120. i64 _int;
  121. f64 _float;
  122. __8B(i64 val) : _int(val) {}
  123. __8B(f64 val) : _float(val) {}
  124. };