codeobject.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #pragma once
  2. #include <stdbool.h>
  3. #include <stdint.h>
  4. #include "pocketpy/common/vector.h"
  5. #include "pocketpy/common/smallmap.h"
  6. #include "pocketpy/objects/base.h"
  7. #include "pocketpy/objects/sourcedata.h"
  8. #include "pocketpy/objects/namedict.h"
  9. #include "pocketpy/pocketpy.h"
  10. #define BC_NOARG 0
  11. #define BC_KEEPLINE -1
  12. #define BC_RETURN_VIRTUAL 5
  13. typedef enum FuncType {
  14. FuncType_UNSET,
  15. FuncType_NORMAL,
  16. FuncType_SIMPLE,
  17. FuncType_GENERATOR,
  18. } FuncType;
  19. typedef enum NameScope {
  20. NAME_LOCAL,
  21. NAME_GLOBAL,
  22. } NameScope;
  23. typedef enum CodeBlockType {
  24. CodeBlockType_NO_BLOCK,
  25. CodeBlockType_WHILE_LOOP,
  26. CodeBlockType_TRY,
  27. /* context blocks (stack-based) */
  28. CodeBlockType_FOR_LOOP,
  29. CodeBlockType_WITH,
  30. /* context blocks (flag-based) */
  31. CodeBlockType_EXCEPT,
  32. } CodeBlockType;
  33. typedef enum Opcode {
  34. #define OPCODE(name) OP_##name,
  35. #include "pocketpy/xmacros/opcodes.h"
  36. #undef OPCODE
  37. } Opcode;
  38. typedef struct Bytecode {
  39. uint16_t op;
  40. uint16_t arg;
  41. } Bytecode;
  42. void Bytecode__set_signed_arg(Bytecode* self, int arg);
  43. bool Bytecode__is_forward_jump(const Bytecode* self);
  44. typedef struct BytecodeEx {
  45. int32_t lineno; // line number for each bytecode
  46. int32_t iblock; // block index
  47. } BytecodeEx;
  48. typedef struct CodeBlock {
  49. int32_t type;
  50. int32_t parent; // parent index in blocks
  51. int32_t start; // start index of this block in codes, inclusive
  52. int32_t end; // end index of this block in codes, exclusive
  53. int32_t end2; // ...
  54. } CodeBlock;
  55. typedef struct CodeObject {
  56. SourceData_ src;
  57. c11_string* name;
  58. c11_vector /*T=Bytecode*/ codes;
  59. c11_vector /*T=CodeObjectByteCodeEx*/ codes_ex;
  60. c11_vector /*T=py_TValue*/ consts; // constants
  61. c11_vector /*T=py_Name*/ varnames; // local variables
  62. c11_vector /*T=py_Name*/ names; // non-local names
  63. int nlocals; // number of local variables
  64. c11_smallmap_n2d varnames_inv;
  65. c11_smallmap_n2d names_inv;
  66. c11_vector /*T=CodeBlock*/ blocks;
  67. c11_vector /*T=FuncDecl_*/ func_decls;
  68. int start_line;
  69. int end_line;
  70. } CodeObject;
  71. void CodeObject__ctor(CodeObject* self, SourceData_ src, c11_sv name);
  72. void CodeObject__dtor(CodeObject* self);
  73. int CodeObject__add_varname(CodeObject* self, py_Name name);
  74. int CodeObject__add_name(CodeObject* self, py_Name name);
  75. void CodeObject__gc_mark(const CodeObject* self, c11_vector* p_stack);
  76. // Serialization
  77. void* CodeObject__dumps(const CodeObject* co, int* size);
  78. char* CodeObject__loads(const void* data, int size, const char* filename, CodeObject* out);
  79. typedef struct FuncDeclKwArg {
  80. int index; // index in co->varnames
  81. py_Name key; // name of this argument
  82. py_TValue value; // default value
  83. } FuncDeclKwArg;
  84. typedef struct FuncDecl {
  85. RefCounted rc;
  86. CodeObject code; // strong ref
  87. c11_vector /*T=int*/ args; // indices in co->varnames
  88. c11_vector /*T=KwArg*/ kwargs; // indices in co->varnames
  89. int starred_arg; // index in co->varnames, -1 if no *arg
  90. int starred_kwarg; // index in co->varnames, -1 if no **kwarg
  91. bool nested; // whether this function is nested
  92. char* docstring;
  93. FuncType type;
  94. c11_smallmap_n2d kw_to_index;
  95. } FuncDecl;
  96. typedef FuncDecl* FuncDecl_;
  97. FuncDecl_ FuncDecl__rcnew(SourceData_ src, c11_sv name);
  98. bool FuncDecl__is_duplicated_arg(const FuncDecl* self, py_Name name);
  99. void FuncDecl__add_arg(FuncDecl* self, py_Name name);
  100. void FuncDecl__add_kwarg(FuncDecl* self, py_Name name, const py_TValue* value);
  101. void FuncDecl__add_starred_arg(FuncDecl* self, py_Name name);
  102. void FuncDecl__add_starred_kwarg(FuncDecl* self, py_Name name);
  103. void FuncDecl__gc_mark(const FuncDecl* self, c11_vector* p_stack);
  104. void FuncDecl__dtor(FuncDecl* self);
  105. // runtime function
  106. typedef struct Function {
  107. FuncDecl_ decl;
  108. py_GlobalRef module; // maybe NULL, weak ref
  109. py_Ref globals; // maybe NULL, strong ref
  110. NameDict* closure; // maybe NULL, strong ref
  111. PyObject* clazz; // weak ref; for super()
  112. py_CFunction cfunc; // wrapped C function; for decl-based binding
  113. } Function;
  114. void Function__ctor(Function* self, FuncDecl_ decl, py_GlobalRef module, py_Ref globals);
  115. void Function__dtor(Function* self);