codeobject.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #pragma once
  2. #include "obj.h"
  3. #include "error.h"
  4. namespace pkpy{
  5. enum NameScope { NAME_LOCAL, NAME_GLOBAL };
  6. enum Opcode {
  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. uint16_t op;
  18. uint16_t block;
  19. int arg;
  20. };
  21. enum CodeBlockType {
  22. NO_BLOCK,
  23. FOR_LOOP,
  24. WHILE_LOOP,
  25. CONTEXT_MANAGER,
  26. TRY_EXCEPT,
  27. };
  28. #define BC_NOARG -1
  29. #define BC_KEEPLINE -1
  30. struct CodeBlock {
  31. CodeBlockType type;
  32. int parent; // parent index in blocks
  33. int for_loop_depth; // this is used for exception handling
  34. int start; // start index of this block in codes, inclusive
  35. int end; // end index of this block in codes, exclusive
  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) {}
  38. };
  39. struct CodeObject {
  40. shared_ptr<SourceData> src;
  41. Str name;
  42. bool is_generator = false;
  43. CodeObject(shared_ptr<SourceData> src, const Str& name):
  44. src(src), name(name) {
  45. varnames_inv = make_sp<NameDictInt>();
  46. labels = make_sp<NameDictInt>();
  47. }
  48. std::vector<Bytecode> codes;
  49. std::vector<int> lines; // line number for each bytecode
  50. List consts;
  51. std::vector<StrName> names; // other names
  52. std::vector<StrName> varnames; // local variables
  53. NameDictInt_ varnames_inv;
  54. std::set<Str> global_names;
  55. std::vector<CodeBlock> blocks = { CodeBlock(NO_BLOCK, -1, 0, 0) };
  56. NameDictInt_ labels;
  57. std::vector<FuncDecl_> func_decls;
  58. void optimize(VM* vm);
  59. void _gc_mark() const {
  60. for(PyObject* v : consts) OBJ_MARK(v);
  61. for(auto& decl: func_decls) decl->_gc_mark();
  62. }
  63. };
  64. } // namespace pkpy