codeobject.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #pragma once
  2. #include "obj.h"
  3. #include "error.h"
  4. namespace pkpy{
  5. enum NameScope { NAME_LOCAL, NAME_GLOBAL, NAME_GLOBAL_UNKNOWN };
  6. enum Opcode: uint8_t {
  7. #define OPCODE(name) OP_##name,
  8. #include "opcodes.h"
  9. #undef OPCODE
  10. };
  11. inline const char* OP_NAMES[] = {
  12. #define OPCODE(name) #name,
  13. #include "opcodes.h"
  14. #undef OPCODE
  15. };
  16. struct Bytecode{
  17. uint8_t op;
  18. uint16_t arg;
  19. };
  20. enum CodeBlockType {
  21. NO_BLOCK,
  22. FOR_LOOP,
  23. WHILE_LOOP,
  24. CONTEXT_MANAGER,
  25. TRY_EXCEPT,
  26. };
  27. inline const uint8_t BC_NOARG = 0;
  28. inline const int BC_KEEPLINE = -1;
  29. struct CodeBlock {
  30. CodeBlockType type;
  31. int parent; // parent index in blocks
  32. int for_loop_depth; // this is used for exception handling
  33. int start; // start index of this block in codes, inclusive
  34. int end; // end index of this block in codes, exclusive
  35. int end2; // ...
  36. CodeBlock(CodeBlockType type, int parent, int for_loop_depth, int start):
  37. type(type), parent(parent), for_loop_depth(for_loop_depth), start(start), end(-1), end2(-1) {}
  38. int get_break_end() const{
  39. if(end2 != -1) return end2;
  40. return end;
  41. }
  42. };
  43. struct CodeObject;
  44. struct FuncDecl;
  45. using CodeObject_ = std::shared_ptr<CodeObject>;
  46. using FuncDecl_ = std::shared_ptr<FuncDecl>;
  47. // struct CodeObjectSerializer{
  48. // std::string buffer;
  49. // int depth = 0;
  50. // std::set<StrName> names;
  51. // static const char END = '\n';
  52. // CodeObjectSerializer();
  53. // void write_int(i64 v);
  54. // void write_float(f64 v);
  55. // void write_str(const Str& v);
  56. // void write_none();
  57. // void write_ellipsis();
  58. // void write_bool(bool v);
  59. // void write_begin_mark();
  60. // void write_name(StrName name);
  61. // void write_end_mark();
  62. // template<typename T>
  63. // void write_bytes(T v){
  64. // static_assert(std::is_trivially_copyable<T>::value);
  65. // buffer += 'x';
  66. // char* p = (char*)&v;
  67. // for(int i=0; i<sizeof(T); i++){
  68. // char c = p[i];
  69. // buffer += "0123456789abcdef"[(c >> 4) & 0xf];
  70. // buffer += "0123456789abcdef"[c & 0xf];
  71. // }
  72. // buffer += END;
  73. // }
  74. // void write_object(VM* vm, PyObject* obj);
  75. // void write_code(VM* vm, const CodeObject* co);
  76. // std::string str();
  77. // };
  78. struct CodeObject {
  79. std::shared_ptr<SourceData> src;
  80. Str name;
  81. bool is_generator = false;
  82. std::vector<Bytecode> codes;
  83. std::vector<int> iblocks; // block index for each bytecode
  84. std::vector<int> lines; // line number for each bytecode
  85. List consts;
  86. std::vector<StrName> varnames; // local variables
  87. NameDictInt varnames_inv;
  88. std::vector<CodeBlock> blocks = { CodeBlock(NO_BLOCK, -1, 0, 0) };
  89. NameDictInt labels;
  90. std::vector<FuncDecl_> func_decls;
  91. const CodeBlock& _get_block_codei(int codei) const{
  92. return blocks[iblocks[codei]];
  93. }
  94. CodeObject(std::shared_ptr<SourceData> src, const Str& name);
  95. void _gc_mark() const;
  96. // void write(VM* vm, CodeObjectSerializer& ss) const;
  97. // Str serialize(VM* vm) const;
  98. };
  99. struct FuncDecl {
  100. struct KwArg {
  101. int key; // index in co->varnames
  102. PyObject* value; // default value
  103. };
  104. CodeObject_ code; // code object of this function
  105. pod_vector<int> args; // indices in co->varnames
  106. pod_vector<KwArg> kwargs; // indices in co->varnames
  107. int starred_arg = -1; // index in co->varnames, -1 if no *arg
  108. int starred_kwarg = -1; // index in co->varnames, -1 if no **kwarg
  109. bool nested = false; // whether this function is nested
  110. Str signature; // signature of this function
  111. Str docstring; // docstring of this function
  112. bool is_simple;
  113. void _gc_mark() const;
  114. };
  115. struct UserData{
  116. char data[15];
  117. bool empty;
  118. UserData(): empty(true) {}
  119. template<typename T>
  120. UserData(T t): empty(false){
  121. static_assert(std::is_trivially_copyable_v<T>);
  122. static_assert(sizeof(T) <= sizeof(data));
  123. memcpy(data, &t, sizeof(T));
  124. }
  125. template <typename T>
  126. T get() const{
  127. static_assert(std::is_trivially_copyable_v<T>);
  128. static_assert(sizeof(T) <= sizeof(data));
  129. #if PK_DEBUG_EXTRA_CHECK
  130. PK_ASSERT(!empty);
  131. #endif
  132. return reinterpret_cast<const T&>(data);
  133. }
  134. };
  135. struct NativeFunc {
  136. NativeFuncC f;
  137. // old style argc-based call
  138. int argc;
  139. // new style decl-based call
  140. FuncDecl_ decl;
  141. UserData _userdata;
  142. void set_userdata(UserData data) {
  143. if(!_userdata.empty && !data.empty){
  144. // override is not supported
  145. throw std::runtime_error("userdata already set");
  146. }
  147. _userdata = data;
  148. }
  149. NativeFunc(NativeFuncC f, int argc, bool method);
  150. NativeFunc(NativeFuncC f, FuncDecl_ decl);
  151. void check_size(VM* vm, ArgsView args) const;
  152. PyObject* call(VM* vm, ArgsView args) const;
  153. };
  154. struct Function{
  155. FuncDecl_ decl;
  156. PyObject* _module; // weak ref
  157. PyObject* _class; // weak ref
  158. NameDict_ _closure;
  159. explicit Function(FuncDecl_ decl, PyObject* _module, PyObject* _class, NameDict_ _closure):
  160. decl(decl), _module(_module), _class(_class), _closure(_closure) {}
  161. };
  162. template<>
  163. struct Py_<Function> final: PyObject {
  164. Function _value;
  165. template<typename... Args>
  166. Py_(Type type, Args&&... args): PyObject(type), _value(std::forward<Args>(args)...) {
  167. _enable_instance_dict();
  168. }
  169. void _obj_gc_mark() override {
  170. _value.decl->_gc_mark();
  171. if(_value._closure != nullptr) gc_mark_namedict(*_value._closure);
  172. }
  173. void* _value_ptr() override {
  174. return &_value;
  175. }
  176. };
  177. template<>
  178. struct Py_<NativeFunc> final: PyObject {
  179. NativeFunc _value;
  180. template<typename... Args>
  181. Py_(Type type, Args&&... args): PyObject(type), _value(std::forward<Args>(args)...) {
  182. _enable_instance_dict();
  183. }
  184. void _obj_gc_mark() override {
  185. if(_value.decl != nullptr){
  186. _value.decl->_gc_mark();
  187. }
  188. }
  189. void* _value_ptr() override {
  190. return &_value;
  191. }
  192. };
  193. template<typename T>
  194. T lambda_get_userdata(PyObject** p){
  195. if(p[-1] != PY_NULL) return PK_OBJ_GET(NativeFunc, p[-1])._userdata.get<T>();
  196. else return PK_OBJ_GET(NativeFunc, p[-2])._userdata.get<T>();
  197. }
  198. } // namespace pkpy