pocketpy.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. #pragma once
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stdarg.h>
  5. /************* Public Types *************/
  6. typedef struct py_TValue py_TValue;
  7. typedef struct pk_VM pk_VM;
  8. typedef uint16_t py_Name;
  9. typedef int16_t py_Type;
  10. typedef int64_t py_i64;
  11. typedef double py_f64;
  12. /// Generic reference.
  13. typedef py_TValue* py_Ref;
  14. /// An object reference which has the same lifespan as the object.
  15. typedef py_TValue* py_ObjectRef;
  16. /// A global reference which has the same lifespan as the VM.
  17. typedef py_TValue* py_GlobalRef;
  18. /// A specific location in the stack.
  19. typedef py_TValue* py_StackRef;
  20. /// A temporary reference which has a short or unknown lifespan.
  21. typedef py_TValue* py_TmpRef;
  22. /// Native function signature.
  23. /// @param argc number of arguments.
  24. /// @param argv array of arguments. Use `py_arg(i)` macro to get the i-th argument.
  25. /// @return true if the function is successful.
  26. typedef bool (*py_CFunction)(int argc, py_StackRef argv);
  27. typedef enum BindType {
  28. BindType_FUNCTION,
  29. BindType_STATICMETHOD,
  30. BindType_CLASSMETHOD,
  31. } BindType;
  32. extern pk_VM* pk_current_vm;
  33. /************* Global VMs *************/
  34. void py_initialize();
  35. void py_finalize();
  36. /// Run a simple source string. Do not change the stack.
  37. bool py_exec(const char*);
  38. /// Eval a simple expression.
  39. /// The result will be set to `py_retval()`.
  40. bool py_eval(const char*);
  41. /************* Values Creation *************/
  42. void py_newint(py_Ref, py_i64);
  43. void py_newfloat(py_Ref, py_f64);
  44. void py_newbool(py_Ref, bool);
  45. void py_newstr(py_Ref, const char*);
  46. void py_newstrn(py_Ref, const char*, int);
  47. // void py_newfstr(py_Ref, const char*, ...);
  48. unsigned char* py_newbytes(py_Ref, int);
  49. void py_newnone(py_Ref);
  50. void py_newnotimplemented(py_Ref out);
  51. void py_newellipsis(py_Ref out);
  52. void py_newnull(py_Ref);
  53. /// Create a tuple with n UNINITIALIZED elements.
  54. /// You should initialize all elements before using it.
  55. void py_newtuple(py_Ref, int n);
  56. /// Create a list.
  57. void py_newlist(py_Ref);
  58. /// Create a list with n UNINITIALIZED elements.
  59. /// You should initialize all elements before using it.
  60. void py_newlistn(py_Ref, int n);
  61. py_Name py_name(const char*);
  62. const char* py_name2str(py_Name);
  63. bool py_ismagicname(py_Name);
  64. // opaque types
  65. void py_newdict(py_Ref);
  66. void py_newset(py_Ref);
  67. void py_newslice(py_Ref, const py_Ref start, const py_Ref stop, const py_Ref step);
  68. // new style decl-based function
  69. void py_newfunction(py_Ref out, py_CFunction, const char* sig);
  70. void py_newfunction2(py_Ref out,
  71. py_CFunction,
  72. const char* sig,
  73. BindType bt,
  74. const char* docstring,
  75. const py_Ref upvalue);
  76. // old style argc-based function
  77. void py_newnativefunc(py_Ref out, py_CFunction);
  78. /// Create a new object.
  79. /// @param out output reference.
  80. /// @param type type of the object.
  81. /// @param slots number of slots. Use -1 to create a `__dict__`.
  82. /// @param udsize size of your userdata. You can use `py_touserdata()` to get the pointer to it.
  83. void py_newobject(py_Ref out, py_Type type, int slots, int udsize);
  84. /************* Type Cast *************/
  85. py_i64 py_toint(const py_Ref);
  86. py_f64 py_tofloat(const py_Ref);
  87. bool py_castfloat(const py_Ref, py_f64* out);
  88. bool py_tobool(const py_Ref);
  89. py_Type py_totype(const py_Ref);
  90. const char* py_tostr(const py_Ref);
  91. const char* py_tostrn(const py_Ref, int* size);
  92. unsigned char* py_tobytes(const py_Ref, int* size);
  93. void* py_touserdata(const py_Ref);
  94. #define py_isint(self) py_istype(self, tp_int)
  95. #define py_isfloat(self) py_istype(self, tp_float)
  96. #define py_isbool(self) py_istype(self, tp_bool)
  97. #define py_isstr(self) py_istype(self, tp_str)
  98. bool py_istype(const py_Ref, py_Type);
  99. bool py_isinstance(const py_Ref obj, py_Type type);
  100. bool py_issubclass(py_Type derived, py_Type base);
  101. /************* References *************/
  102. #define py_offset(p, i) (py_Ref)((char*)p + ((i) << 4))
  103. #define TypeError(x) false
  104. #define py_arg(i) py_offset(argv, i)
  105. #define py_checkargc(n) \
  106. if(argc != n) return TypeError()
  107. py_GlobalRef py_tpmagic(py_Type type, py_Name name);
  108. #define py_bindmagic(type, __magic__, f) py_newnativefunc(py_tpmagic((type), __magic__), (f))
  109. // new style decl-based bindings
  110. py_TmpRef py_bind(py_Ref obj, const char* sig, py_CFunction f);
  111. py_TmpRef py_bind2(py_Ref obj,
  112. const char* sig,
  113. py_CFunction f,
  114. BindType bt,
  115. const char* docstring,
  116. const py_Ref upvalue);
  117. // old style argc-based bindings
  118. void py_bindmethod(py_Type type, const char* name, py_CFunction f);
  119. void py_bindmethod2(py_Type type, const char* name, py_CFunction f, BindType bt);
  120. void py_bindnativefunc(py_Ref obj, const char* name, py_CFunction f);
  121. /// Get the reference to the i-th register.
  122. py_GlobalRef py_reg(int i);
  123. /// Get the reference of the object's `__dict__`.
  124. /// The object must have a `__dict__`.
  125. /// Returns a reference to the value or NULL if not found.
  126. /// @lifespan: Object.
  127. py_ObjectRef py_getdict(const py_Ref self, py_Name name);
  128. void py_setdict(py_Ref self, py_Name name, const py_Ref val);
  129. /// Get the reference of the i-th slot of the object.
  130. /// The object must have slots and `i` must be in range.
  131. /// @lifespan: Object.
  132. py_ObjectRef py_getslot(const py_Ref self, int i);
  133. void py_setslot(py_Ref self, int i, const py_Ref val);
  134. py_TmpRef py_getupvalue(py_StackRef argv);
  135. void py_setupvalue(py_StackRef argv, const py_Ref val);
  136. /// Gets the attribute of the object.
  137. bool py_getattr(const py_Ref self, py_Name name, py_Ref out);
  138. /// Gets the unbound method of the object.
  139. bool py_getunboundmethod(const py_Ref self,
  140. py_Name name,
  141. bool fallback,
  142. py_Ref out,
  143. py_Ref out_self);
  144. /// Sets the attribute of the object.
  145. bool py_setattr(py_Ref self, py_Name name, const py_Ref val);
  146. /// Deletes the attribute of the object.
  147. bool py_delattr(py_Ref self, py_Name name);
  148. bool py_getitem(const py_Ref self, const py_Ref key, py_Ref out);
  149. bool py_setitem(py_Ref self, const py_Ref key, const py_Ref val);
  150. bool py_delitem(py_Ref self, const py_Ref key);
  151. /// Perform a binary operation on the stack.
  152. /// It assumes `lhs` and `rhs` are already pushed to the stack.
  153. /// The result will be set to `py_retval()`.
  154. bool py_binaryop(const py_Ref lhs, const py_Ref rhs, py_Name op, py_Name rop);
  155. #define py_binaryadd(lhs, rhs) py_binaryop(lhs, rhs, __add__, __radd__)
  156. #define py_binarysub(lhs, rhs) py_binaryop(lhs, rhs, __sub__, __rsub__)
  157. #define py_binarymul(lhs, rhs) py_binaryop(lhs, rhs, __mul__, __rmul__)
  158. #define py_binarytruediv(lhs, rhs) py_binaryop(lhs, rhs, __truediv__, __rtruediv__)
  159. #define py_binaryfloordiv(lhs, rhs) py_binaryop(lhs, rhs, __floordiv__, __rfloordiv__)
  160. #define py_binarymod(lhs, rhs) py_binaryop(lhs, rhs, __mod__, __rmod__)
  161. #define py_binarypow(lhs, rhs) py_binaryop(lhs, rhs, __pow__, __rpow__)
  162. #define py_binarylshift(lhs, rhs) py_binaryop(lhs, rhs, __lshift__, 0)
  163. #define py_binaryrshift(lhs, rhs) py_binaryop(lhs, rhs, __rshift__, 0)
  164. #define py_binaryand(lhs, rhs) py_binaryop(lhs, rhs, __and__, 0)
  165. #define py_binaryor(lhs, rhs) py_binaryop(lhs, rhs, __or__, 0)
  166. #define py_binaryxor(lhs, rhs) py_binaryop(lhs, rhs, __xor__, 0)
  167. #define py_binarymatmul(lhs, rhs) py_binaryop(lhs, rhs, __matmul__, 0)
  168. /// Equivalent to `*dst = *src`.
  169. void py_assign(py_Ref dst, const py_Ref src);
  170. /************* Stack Operations *************/
  171. /// Returns a reference to the i-th object from the top of the stack.
  172. /// i should be negative, e.g. (-1) means TOS.
  173. py_StackRef py_peek(int i);
  174. /// Pushes the object to the stack.
  175. void py_push(const py_Ref src);
  176. /// Pops an object from the stack.
  177. void py_pop();
  178. /// Shrink the stack by n.
  179. void py_shrink(int n);
  180. /// Get a temporary variable from the stack and returns the reference to it.
  181. py_StackRef py_pushtmp();
  182. /// Free n temporary variable.
  183. #define py_poptmp(n) py_shrink(n)
  184. #define py_gettop() py_peek(-1)
  185. #define py_getsecond() py_peek(-2)
  186. #define py_settop(v) py_assign(py_peek(-1), v)
  187. #define py_setsecond(v) py_assign(py_peek(-2), v)
  188. #define py_duptop() py_push(py_peek(-1))
  189. #define py_dupsecond() py_push(py_peek(-2))
  190. /************* Modules *************/
  191. py_TmpRef py_newmodule(const char* name, const char* package);
  192. py_TmpRef py_getmodule(const char* name);
  193. /// Import a module.
  194. /// The result will be set to `py_retval()`.
  195. bool py_import(const char* name);
  196. /************* Errors *************/
  197. /// Print the last error to the console.
  198. void py_printexc();
  199. /// Format the last error to a string.
  200. void py_formatexc(char* out);
  201. /************* Operators *************/
  202. /// Equivalent to `bool(val)`.
  203. /// Returns 1 if `val` is truthy, otherwise 0.
  204. /// Returns -1 if an error occurred.
  205. int py_bool(const py_Ref val);
  206. int py_eq(const py_Ref, const py_Ref);
  207. int py_ne(const py_Ref, const py_Ref);
  208. int py_le(const py_Ref, const py_Ref);
  209. int py_lt(const py_Ref, const py_Ref);
  210. int py_ge(const py_Ref, const py_Ref);
  211. int py_gt(const py_Ref, const py_Ref);
  212. bool py_hash(const py_Ref, py_i64* out);
  213. /// Python equivalent to `lhs is rhs`.
  214. bool py_isidentical(const py_Ref, const py_Ref);
  215. /// A stack operation that calls a function.
  216. /// It assumes `argc + kwargc` arguments are already pushed to the stack.
  217. /// The result will be set to `py_retval()`.
  218. /// The stack size will be reduced by `argc + kwargc`.
  219. bool pk_vectorcall(int argc, int kwargc, bool op_call);
  220. /// Call a function.
  221. /// It prepares the stack and then performs a `vectorcall(argc, 0, false)`.
  222. /// The result will be set to `py_retval()`.
  223. /// The stack remains unchanged after the operation.
  224. bool py_call(py_Ref f, int argc, py_Ref argv);
  225. /// Call a non-magic method.
  226. /// It prepares the stack and then performs a `vectorcall(argc+1, 0, false)`.
  227. /// The result will be set to `py_retval()`.
  228. /// The stack remains unchanged after the operation.
  229. bool py_callmethod(py_Ref self, py_Name, int argc, py_Ref argv);
  230. /// Call a magic method using a continuous buffer.
  231. /// The result will be set to `py_retval()`.
  232. /// The stack remains unchanged after the operation.
  233. bool py_callmagic(py_Name name, int argc, py_Ref argv);
  234. #define py_repr(self) py_callmagic(__repr__, 1, self)
  235. #define py_str(self) py_callmagic(__str__, 1, self)
  236. /// The return value of the most recent call.
  237. py_GlobalRef py_retval();
  238. #define py_isnull(self) ((self)->type == 0)
  239. /* tuple */
  240. // unchecked functions, if self is not a tuple, the behavior is undefined
  241. py_ObjectRef py_tuple__getitem(const py_Ref self, int i);
  242. void py_tuple__setitem(py_Ref self, int i, const py_Ref val);
  243. int py_tuple__len(const py_Ref self);
  244. // unchecked functions, if self is not a list, the behavior is undefined
  245. py_ObjectRef py_list__getitem(const py_Ref self, int i);
  246. void py_list__setitem(py_Ref self, int i, const py_Ref val);
  247. void py_list__delitem(py_Ref self, int i);
  248. int py_list__len(const py_Ref self);
  249. void py_list__append(py_Ref self, const py_Ref val);
  250. void py_list__clear(py_Ref self);
  251. void py_list__insert(py_Ref self, int i, const py_Ref val);
  252. // internal functions
  253. typedef struct pk_TypeInfo pk_TypeInfo;
  254. pk_TypeInfo* pk_tpinfo(const py_Ref self);
  255. /// Search the magic method from the given type to the base type.
  256. /// Return the reference or NULL if not found.
  257. py_GlobalRef py_tpfindmagic(py_Type, py_Name name);
  258. /// Get the type object of the given type.
  259. py_GlobalRef py_tpobject(py_Type type);
  260. /// Get the type name.
  261. const char* py_tpname(py_Type type);
  262. /// Check if the object is an instance of the given type.
  263. /// Re
  264. bool py_checktype(const py_Ref self, py_Type type);
  265. /// Python favored string formatting.
  266. /// %d: int
  267. /// %i: py_i64 (int64_t)
  268. /// %f: py_f64 (double)
  269. /// %s: const char*
  270. /// %q: single quoted %s
  271. /// %c: char
  272. /// %p: void*
  273. /// %t: py_Type
  274. /// %n: py_Name
  275. #define MAGIC_METHOD(x) extern uint16_t x;
  276. #include "pocketpy/xmacros/magics.h"
  277. #undef MAGIC_METHOD
  278. #ifdef __cplusplus
  279. }
  280. #endif