CPy.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. // Mypyc C API
  2. #ifndef CPY_CPY_H
  3. #define CPY_CPY_H
  4. #include <stdbool.h>
  5. #include <Python.h>
  6. #include <frameobject.h>
  7. #include <structmember.h>
  8. #include <assert.h>
  9. #include <stdint.h>
  10. #include "pythonsupport.h"
  11. #include "mypyc_util.h"
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. #if 0
  16. } // why isn't emacs smart enough to not indent this
  17. #endif
  18. #define CPYTHON_LARGE_INT_ERRMSG "Python int too large to convert to C ssize_t"
  19. // Naming conventions:
  20. //
  21. // Tagged: tagged int
  22. // Long: tagged long int (pointer)
  23. // Short: tagged short int (unboxed)
  24. // Ssize_t: A Py_ssize_t, which ought to be the same width as pointers
  25. // Object: CPython object (PyObject *)
  26. // Tuple type definitions needed for API functions
  27. #ifndef MYPYC_DECLARED_tuple_T3OOO
  28. #define MYPYC_DECLARED_tuple_T3OOO
  29. typedef struct tuple_T3OOO {
  30. PyObject *f0;
  31. PyObject *f1;
  32. PyObject *f2;
  33. } tuple_T3OOO;
  34. #endif
  35. // Our return tuple wrapper for dictionary iteration helper.
  36. #ifndef MYPYC_DECLARED_tuple_T3CIO
  37. #define MYPYC_DECLARED_tuple_T3CIO
  38. typedef struct tuple_T3CIO {
  39. char f0; // Should continue?
  40. CPyTagged f1; // Last dict offset
  41. PyObject *f2; // Next dictionary key or value
  42. } tuple_T3CIO;
  43. #endif
  44. // Same as above but for both key and value.
  45. #ifndef MYPYC_DECLARED_tuple_T4CIOO
  46. #define MYPYC_DECLARED_tuple_T4CIOO
  47. typedef struct tuple_T4CIOO {
  48. char f0; // Should continue?
  49. CPyTagged f1; // Last dict offset
  50. PyObject *f2; // Next dictionary key
  51. PyObject *f3; // Next dictionary value
  52. } tuple_T4CIOO;
  53. #endif
  54. // Native object operations
  55. // Search backwards through the trait part of a vtable (which sits *before*
  56. // the start of the vtable proper) looking for the subvtable describing a trait
  57. // implementation. We don't do any bounds checking so we'd better be pretty sure
  58. // we know that it is there.
  59. static inline CPyVTableItem *CPy_FindTraitVtable(PyTypeObject *trait, CPyVTableItem *vtable) {
  60. int i;
  61. for (i = -3; ; i -= 3) {
  62. if ((PyTypeObject *)vtable[i] == trait) {
  63. return (CPyVTableItem *)vtable[i + 1];
  64. }
  65. }
  66. }
  67. // Use the same logic for offset table.
  68. static inline size_t CPy_FindAttrOffset(PyTypeObject *trait, CPyVTableItem *vtable, size_t index) {
  69. int i;
  70. for (i = -3; ; i -= 3) {
  71. if ((PyTypeObject *)vtable[i] == trait) {
  72. return ((size_t *)vtable[i + 2])[index];
  73. }
  74. }
  75. }
  76. // Get attribute value using vtable (may return an undefined value)
  77. #define CPY_GET_ATTR(obj, type, vtable_index, object_type, attr_type) \
  78. ((attr_type (*)(object_type *))((object_type *)obj)->vtable[vtable_index])((object_type *)obj)
  79. #define CPY_GET_ATTR_TRAIT(obj, trait, vtable_index, object_type, attr_type) \
  80. ((attr_type (*)(object_type *))(CPy_FindTraitVtable(trait, ((object_type *)obj)->vtable))[vtable_index])((object_type *)obj)
  81. // Set attribute value using vtable
  82. #define CPY_SET_ATTR(obj, type, vtable_index, value, object_type, attr_type) \
  83. ((bool (*)(object_type *, attr_type))((object_type *)obj)->vtable[vtable_index])( \
  84. (object_type *)obj, value)
  85. #define CPY_SET_ATTR_TRAIT(obj, trait, vtable_index, value, object_type, attr_type) \
  86. ((bool (*)(object_type *, attr_type))(CPy_FindTraitVtable(trait, ((object_type *)obj)->vtable))[vtable_index])( \
  87. (object_type *)obj, value)
  88. #define CPY_GET_METHOD(obj, type, vtable_index, object_type, method_type) \
  89. ((method_type)(((object_type *)obj)->vtable[vtable_index]))
  90. #define CPY_GET_METHOD_TRAIT(obj, trait, vtable_index, object_type, method_type) \
  91. ((method_type)(CPy_FindTraitVtable(trait, ((object_type *)obj)->vtable)[vtable_index]))
  92. // Int operations
  93. CPyTagged CPyTagged_FromSsize_t(Py_ssize_t value);
  94. CPyTagged CPyTagged_FromVoidPtr(void *ptr);
  95. CPyTagged CPyTagged_FromInt64(int64_t value);
  96. CPyTagged CPyTagged_FromObject(PyObject *object);
  97. CPyTagged CPyTagged_StealFromObject(PyObject *object);
  98. CPyTagged CPyTagged_BorrowFromObject(PyObject *object);
  99. PyObject *CPyTagged_AsObject(CPyTagged x);
  100. PyObject *CPyTagged_StealAsObject(CPyTagged x);
  101. Py_ssize_t CPyTagged_AsSsize_t(CPyTagged x);
  102. void CPyTagged_IncRef(CPyTagged x);
  103. void CPyTagged_DecRef(CPyTagged x);
  104. void CPyTagged_XDecRef(CPyTagged x);
  105. CPyTagged CPyTagged_Negate(CPyTagged num);
  106. CPyTagged CPyTagged_Invert(CPyTagged num);
  107. CPyTagged CPyTagged_Add(CPyTagged left, CPyTagged right);
  108. CPyTagged CPyTagged_Subtract(CPyTagged left, CPyTagged right);
  109. CPyTagged CPyTagged_Multiply(CPyTagged left, CPyTagged right);
  110. CPyTagged CPyTagged_FloorDivide(CPyTagged left, CPyTagged right);
  111. CPyTagged CPyTagged_Remainder(CPyTagged left, CPyTagged right);
  112. CPyTagged CPyTagged_And(CPyTagged left, CPyTagged right);
  113. CPyTagged CPyTagged_Or(CPyTagged left, CPyTagged right);
  114. CPyTagged CPyTagged_Xor(CPyTagged left, CPyTagged right);
  115. CPyTagged CPyTagged_Rshift(CPyTagged left, CPyTagged right);
  116. CPyTagged CPyTagged_Lshift(CPyTagged left, CPyTagged right);
  117. bool CPyTagged_IsEq_(CPyTagged left, CPyTagged right);
  118. bool CPyTagged_IsLt_(CPyTagged left, CPyTagged right);
  119. PyObject *CPyTagged_Str(CPyTagged n);
  120. CPyTagged CPyTagged_FromFloat(double f);
  121. PyObject *CPyLong_FromStrWithBase(PyObject *o, CPyTagged base);
  122. PyObject *CPyLong_FromStr(PyObject *o);
  123. PyObject *CPyBool_Str(bool b);
  124. int64_t CPyLong_AsInt64(PyObject *o);
  125. int64_t CPyInt64_Divide(int64_t x, int64_t y);
  126. int64_t CPyInt64_Remainder(int64_t x, int64_t y);
  127. int32_t CPyLong_AsInt32(PyObject *o);
  128. int32_t CPyInt32_Divide(int32_t x, int32_t y);
  129. int32_t CPyInt32_Remainder(int32_t x, int32_t y);
  130. void CPyInt32_Overflow(void);
  131. int16_t CPyLong_AsInt16(PyObject *o);
  132. int16_t CPyInt16_Divide(int16_t x, int16_t y);
  133. int16_t CPyInt16_Remainder(int16_t x, int16_t y);
  134. void CPyInt16_Overflow(void);
  135. uint8_t CPyLong_AsUInt8(PyObject *o);
  136. void CPyUInt8_Overflow(void);
  137. double CPyTagged_TrueDivide(CPyTagged x, CPyTagged y);
  138. static inline int CPyTagged_CheckLong(CPyTagged x) {
  139. return x & CPY_INT_TAG;
  140. }
  141. static inline int CPyTagged_CheckShort(CPyTagged x) {
  142. return !CPyTagged_CheckLong(x);
  143. }
  144. static inline void CPyTagged_INCREF(CPyTagged x) {
  145. if (unlikely(CPyTagged_CheckLong(x))) {
  146. CPyTagged_IncRef(x);
  147. }
  148. }
  149. static inline void CPyTagged_DECREF(CPyTagged x) {
  150. if (unlikely(CPyTagged_CheckLong(x))) {
  151. CPyTagged_DecRef(x);
  152. }
  153. }
  154. static inline void CPyTagged_XDECREF(CPyTagged x) {
  155. if (unlikely(CPyTagged_CheckLong(x))) {
  156. CPyTagged_XDecRef(x);
  157. }
  158. }
  159. static inline Py_ssize_t CPyTagged_ShortAsSsize_t(CPyTagged x) {
  160. // NOTE: Assume that we sign extend.
  161. return (Py_ssize_t)x >> 1;
  162. }
  163. static inline PyObject *CPyTagged_LongAsObject(CPyTagged x) {
  164. // NOTE: Assume target is not a short int.
  165. return (PyObject *)(x & ~CPY_INT_TAG);
  166. }
  167. static inline bool CPyTagged_TooBig(Py_ssize_t value) {
  168. // Micro-optimized for the common case where it fits.
  169. return (size_t)value > CPY_TAGGED_MAX
  170. && (value >= 0 || value < CPY_TAGGED_MIN);
  171. }
  172. static inline bool CPyTagged_TooBigInt64(int64_t value) {
  173. // Micro-optimized for the common case where it fits.
  174. return (uint64_t)value > CPY_TAGGED_MAX
  175. && (value >= 0 || value < CPY_TAGGED_MIN);
  176. }
  177. static inline bool CPyTagged_IsAddOverflow(CPyTagged sum, CPyTagged left, CPyTagged right) {
  178. // This check was copied from some of my old code I believe that it works :-)
  179. return (Py_ssize_t)(sum ^ left) < 0 && (Py_ssize_t)(sum ^ right) < 0;
  180. }
  181. static inline bool CPyTagged_IsSubtractOverflow(CPyTagged diff, CPyTagged left, CPyTagged right) {
  182. // This check was copied from some of my old code I believe that it works :-)
  183. return (Py_ssize_t)(diff ^ left) < 0 && (Py_ssize_t)(diff ^ right) >= 0;
  184. }
  185. static inline bool CPyTagged_IsMultiplyOverflow(CPyTagged left, CPyTagged right) {
  186. // This is conservative -- return false only in a small number of all non-overflow cases
  187. return left >= (1U << (CPY_INT_BITS/2 - 1)) || right >= (1U << (CPY_INT_BITS/2 - 1));
  188. }
  189. static inline bool CPyTagged_MaybeFloorDivideFault(CPyTagged left, CPyTagged right) {
  190. return right == 0 || left == -((size_t)1 << (CPY_INT_BITS-1));
  191. }
  192. static inline bool CPyTagged_MaybeRemainderFault(CPyTagged left, CPyTagged right) {
  193. // Division/modulus can fault when dividing INT_MIN by -1, but we
  194. // do our mods on still-tagged integers with the low-bit clear, so
  195. // -1 is actually represented as -2 and can't overflow.
  196. // Mod by 0 can still fault though.
  197. return right == 0;
  198. }
  199. static inline bool CPyTagged_IsEq(CPyTagged left, CPyTagged right) {
  200. if (CPyTagged_CheckShort(left)) {
  201. return left == right;
  202. } else {
  203. return CPyTagged_IsEq_(left, right);
  204. }
  205. }
  206. static inline bool CPyTagged_IsNe(CPyTagged left, CPyTagged right) {
  207. if (CPyTagged_CheckShort(left)) {
  208. return left != right;
  209. } else {
  210. return !CPyTagged_IsEq_(left, right);
  211. }
  212. }
  213. static inline bool CPyTagged_IsLt(CPyTagged left, CPyTagged right) {
  214. if (CPyTagged_CheckShort(left) && CPyTagged_CheckShort(right)) {
  215. return (Py_ssize_t)left < (Py_ssize_t)right;
  216. } else {
  217. return CPyTagged_IsLt_(left, right);
  218. }
  219. }
  220. static inline bool CPyTagged_IsGe(CPyTagged left, CPyTagged right) {
  221. if (CPyTagged_CheckShort(left) && CPyTagged_CheckShort(right)) {
  222. return (Py_ssize_t)left >= (Py_ssize_t)right;
  223. } else {
  224. return !CPyTagged_IsLt_(left, right);
  225. }
  226. }
  227. static inline bool CPyTagged_IsGt(CPyTagged left, CPyTagged right) {
  228. if (CPyTagged_CheckShort(left) && CPyTagged_CheckShort(right)) {
  229. return (Py_ssize_t)left > (Py_ssize_t)right;
  230. } else {
  231. return CPyTagged_IsLt_(right, left);
  232. }
  233. }
  234. static inline bool CPyTagged_IsLe(CPyTagged left, CPyTagged right) {
  235. if (CPyTagged_CheckShort(left) && CPyTagged_CheckShort(right)) {
  236. return (Py_ssize_t)left <= (Py_ssize_t)right;
  237. } else {
  238. return !CPyTagged_IsLt_(right, left);
  239. }
  240. }
  241. // Float operations
  242. double CPyFloat_FloorDivide(double x, double y);
  243. double CPyFloat_Pow(double x, double y);
  244. double CPyFloat_Sin(double x);
  245. double CPyFloat_Cos(double x);
  246. double CPyFloat_Tan(double x);
  247. double CPyFloat_Sqrt(double x);
  248. double CPyFloat_Exp(double x);
  249. double CPyFloat_Log(double x);
  250. CPyTagged CPyFloat_Floor(double x);
  251. CPyTagged CPyFloat_Ceil(double x);
  252. double CPyFloat_FromTagged(CPyTagged x);
  253. bool CPyFloat_IsInf(double x);
  254. bool CPyFloat_IsNaN(double x);
  255. // Generic operations (that work with arbitrary types)
  256. /* We use intentionally non-inlined decrefs in rarely executed code
  257. * paths since it pretty substantially speeds up compile time. We have
  258. * our own copies both to avoid the null check in Py_DecRef and to avoid
  259. * making an indirect PIC call. */
  260. CPy_NOINLINE
  261. static void CPy_DecRef(PyObject *p) {
  262. CPy_DECREF(p);
  263. }
  264. CPy_NOINLINE
  265. static void CPy_XDecRef(PyObject *p) {
  266. CPy_XDECREF(p);
  267. }
  268. static inline CPyTagged CPyObject_Size(PyObject *obj) {
  269. Py_ssize_t s = PyObject_Size(obj);
  270. if (s < 0) {
  271. return CPY_INT_TAG;
  272. } else {
  273. // Technically __len__ could return a really big number, so we
  274. // should allow this to produce a boxed int. In practice it
  275. // shouldn't ever if the data structure actually contains all
  276. // the elements, but...
  277. return CPyTagged_FromSsize_t(s);
  278. }
  279. }
  280. #ifdef MYPYC_LOG_GETATTR
  281. static void CPy_LogGetAttr(const char *method, PyObject *obj, PyObject *attr) {
  282. PyObject *module = PyImport_ImportModule("getattr_hook");
  283. if (module) {
  284. PyObject *res = PyObject_CallMethodObjArgs(module, method, obj, attr, NULL);
  285. Py_XDECREF(res);
  286. Py_DECREF(module);
  287. }
  288. PyErr_Clear();
  289. }
  290. #else
  291. #define CPy_LogGetAttr(method, obj, attr) (void)0
  292. #endif
  293. // Intercept a method call and log it. This needs to be a macro
  294. // because there is no API that accepts va_args for making a
  295. // call. Worse, it needs to use the comma operator to return the right
  296. // value.
  297. #define CPyObject_CallMethodObjArgs(obj, attr, ...) \
  298. (CPy_LogGetAttr("log_method", (obj), (attr)), \
  299. PyObject_CallMethodObjArgs((obj), (attr), __VA_ARGS__))
  300. // This one is a macro for consistency with the above, I guess.
  301. #define CPyObject_GetAttr(obj, attr) \
  302. (CPy_LogGetAttr("log", (obj), (attr)), \
  303. PyObject_GetAttr((obj), (attr)))
  304. CPyTagged CPyObject_Hash(PyObject *o);
  305. PyObject *CPyObject_GetAttr3(PyObject *v, PyObject *name, PyObject *defl);
  306. PyObject *CPyIter_Next(PyObject *iter);
  307. PyObject *CPyNumber_Power(PyObject *base, PyObject *index);
  308. PyObject *CPyNumber_InPlacePower(PyObject *base, PyObject *index);
  309. PyObject *CPyObject_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
  310. // List operations
  311. PyObject *CPyList_Build(Py_ssize_t len, ...);
  312. PyObject *CPyList_GetItem(PyObject *list, CPyTagged index);
  313. PyObject *CPyList_GetItemUnsafe(PyObject *list, CPyTagged index);
  314. PyObject *CPyList_GetItemShort(PyObject *list, CPyTagged index);
  315. PyObject *CPyList_GetItemBorrow(PyObject *list, CPyTagged index);
  316. PyObject *CPyList_GetItemShortBorrow(PyObject *list, CPyTagged index);
  317. PyObject *CPyList_GetItemInt64(PyObject *list, int64_t index);
  318. PyObject *CPyList_GetItemInt64Borrow(PyObject *list, int64_t index);
  319. bool CPyList_SetItem(PyObject *list, CPyTagged index, PyObject *value);
  320. bool CPyList_SetItemUnsafe(PyObject *list, CPyTagged index, PyObject *value);
  321. bool CPyList_SetItemInt64(PyObject *list, int64_t index, PyObject *value);
  322. PyObject *CPyList_PopLast(PyObject *obj);
  323. PyObject *CPyList_Pop(PyObject *obj, CPyTagged index);
  324. CPyTagged CPyList_Count(PyObject *obj, PyObject *value);
  325. int CPyList_Insert(PyObject *list, CPyTagged index, PyObject *value);
  326. PyObject *CPyList_Extend(PyObject *o1, PyObject *o2);
  327. int CPyList_Remove(PyObject *list, PyObject *obj);
  328. CPyTagged CPyList_Index(PyObject *list, PyObject *obj);
  329. PyObject *CPySequence_Multiply(PyObject *seq, CPyTagged t_size);
  330. PyObject *CPySequence_RMultiply(CPyTagged t_size, PyObject *seq);
  331. PyObject *CPyList_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
  332. int CPySequence_Check(PyObject *obj);
  333. // Dict operations
  334. PyObject *CPyDict_GetItem(PyObject *dict, PyObject *key);
  335. int CPyDict_SetItem(PyObject *dict, PyObject *key, PyObject *value);
  336. PyObject *CPyDict_Get(PyObject *dict, PyObject *key, PyObject *fallback);
  337. PyObject *CPyDict_GetWithNone(PyObject *dict, PyObject *key);
  338. PyObject *CPyDict_SetDefault(PyObject *dict, PyObject *key, PyObject *value);
  339. PyObject *CPyDict_SetDefaultWithNone(PyObject *dict, PyObject *key);
  340. PyObject *CPyDict_SetDefaultWithEmptyDatatype(PyObject *dict, PyObject *key, int data_type);
  341. PyObject *CPyDict_Build(Py_ssize_t size, ...);
  342. int CPyDict_Update(PyObject *dict, PyObject *stuff);
  343. int CPyDict_UpdateInDisplay(PyObject *dict, PyObject *stuff);
  344. int CPyDict_UpdateFromAny(PyObject *dict, PyObject *stuff);
  345. PyObject *CPyDict_FromAny(PyObject *obj);
  346. PyObject *CPyDict_KeysView(PyObject *dict);
  347. PyObject *CPyDict_ValuesView(PyObject *dict);
  348. PyObject *CPyDict_ItemsView(PyObject *dict);
  349. PyObject *CPyDict_Keys(PyObject *dict);
  350. PyObject *CPyDict_Values(PyObject *dict);
  351. PyObject *CPyDict_Items(PyObject *dict);
  352. char CPyDict_Clear(PyObject *dict);
  353. PyObject *CPyDict_Copy(PyObject *dict);
  354. PyObject *CPyDict_GetKeysIter(PyObject *dict);
  355. PyObject *CPyDict_GetItemsIter(PyObject *dict);
  356. PyObject *CPyDict_GetValuesIter(PyObject *dict);
  357. tuple_T3CIO CPyDict_NextKey(PyObject *dict_or_iter, CPyTagged offset);
  358. tuple_T3CIO CPyDict_NextValue(PyObject *dict_or_iter, CPyTagged offset);
  359. tuple_T4CIOO CPyDict_NextItem(PyObject *dict_or_iter, CPyTagged offset);
  360. int CPyMapping_Check(PyObject *obj);
  361. // Check that dictionary didn't change size during iteration.
  362. static inline char CPyDict_CheckSize(PyObject *dict, CPyTagged size) {
  363. if (!PyDict_CheckExact(dict)) {
  364. // Dict subclasses will be checked by Python runtime.
  365. return 1;
  366. }
  367. Py_ssize_t py_size = CPyTagged_AsSsize_t(size);
  368. Py_ssize_t dict_size = PyDict_Size(dict);
  369. if (py_size != dict_size) {
  370. PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration");
  371. return 0;
  372. }
  373. return 1;
  374. }
  375. // Str operations
  376. PyObject *CPyStr_Build(Py_ssize_t len, ...);
  377. PyObject *CPyStr_GetItem(PyObject *str, CPyTagged index);
  378. PyObject *CPyStr_Split(PyObject *str, PyObject *sep, CPyTagged max_split);
  379. PyObject *CPyStr_Replace(PyObject *str, PyObject *old_substr, PyObject *new_substr, CPyTagged max_replace);
  380. PyObject *CPyStr_Append(PyObject *o1, PyObject *o2);
  381. PyObject *CPyStr_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
  382. bool CPyStr_Startswith(PyObject *self, PyObject *subobj);
  383. bool CPyStr_Endswith(PyObject *self, PyObject *subobj);
  384. bool CPyStr_IsTrue(PyObject *obj);
  385. Py_ssize_t CPyStr_Size_size_t(PyObject *str);
  386. PyObject *CPy_Decode(PyObject *obj, PyObject *encoding, PyObject *errors);
  387. PyObject *CPy_Encode(PyObject *obj, PyObject *encoding, PyObject *errors);
  388. // Bytes operations
  389. PyObject *CPyBytes_Build(Py_ssize_t len, ...);
  390. PyObject *CPyBytes_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
  391. CPyTagged CPyBytes_GetItem(PyObject *o, CPyTagged index);
  392. PyObject *CPyBytes_Concat(PyObject *a, PyObject *b);
  393. PyObject *CPyBytes_Join(PyObject *sep, PyObject *iter);
  394. int CPyBytes_Compare(PyObject *left, PyObject *right);
  395. // Set operations
  396. bool CPySet_Remove(PyObject *set, PyObject *key);
  397. // Tuple operations
  398. PyObject *CPySequenceTuple_GetItem(PyObject *tuple, CPyTagged index);
  399. PyObject *CPySequenceTuple_GetSlice(PyObject *obj, CPyTagged start, CPyTagged end);
  400. bool CPySequenceTuple_SetItemUnsafe(PyObject *tuple, CPyTagged index, PyObject *value);
  401. // Exception operations
  402. // mypyc is not very good at dealing with refcount management of
  403. // pointers that might be NULL. As a workaround for this, the
  404. // exception APIs that might want to return NULL pointers instead
  405. // return properly refcounted pointers to this dummy object.
  406. struct ExcDummyStruct { PyObject_HEAD };
  407. extern struct ExcDummyStruct _CPy_ExcDummyStruct;
  408. extern PyObject *_CPy_ExcDummy;
  409. static inline void _CPy_ToDummy(PyObject **p) {
  410. if (*p == NULL) {
  411. Py_INCREF(_CPy_ExcDummy);
  412. *p = _CPy_ExcDummy;
  413. }
  414. }
  415. static inline PyObject *_CPy_FromDummy(PyObject *p) {
  416. if (p == _CPy_ExcDummy) return NULL;
  417. Py_INCREF(p);
  418. return p;
  419. }
  420. static int CPy_NoErrOccured(void) {
  421. return PyErr_Occurred() == NULL;
  422. }
  423. static inline bool CPy_KeepPropagating(void) {
  424. return 0;
  425. }
  426. // We want to avoid the public PyErr_GetExcInfo API for these because
  427. // it requires a bunch of spurious refcount traffic on the parts of
  428. // the triple we don't care about.
  429. #define CPy_ExcState() PyThreadState_GET()->exc_info
  430. void CPy_Raise(PyObject *exc);
  431. void CPy_Reraise(void);
  432. void CPyErr_SetObjectAndTraceback(PyObject *type, PyObject *value, PyObject *traceback);
  433. tuple_T3OOO CPy_CatchError(void);
  434. void CPy_RestoreExcInfo(tuple_T3OOO info);
  435. bool CPy_ExceptionMatches(PyObject *type);
  436. PyObject *CPy_GetExcValue(void);
  437. tuple_T3OOO CPy_GetExcInfo(void);
  438. void _CPy_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback);
  439. void CPyError_OutOfMemory(void);
  440. void CPy_TypeError(const char *expected, PyObject *value);
  441. void CPy_AddTraceback(const char *filename, const char *funcname, int line, PyObject *globals);
  442. void CPy_TypeErrorTraceback(const char *filename, const char *funcname, int line,
  443. PyObject *globals, const char *expected, PyObject *value);
  444. void CPy_AttributeError(const char *filename, const char *funcname, const char *classname,
  445. const char *attrname, int line, PyObject *globals);
  446. // Misc operations
  447. #if PY_VERSION_HEX >= 0x03080000
  448. #define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc)
  449. #define CPy_TRASHCAN_END(op) Py_TRASHCAN_END
  450. #else
  451. #define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_SAFE_BEGIN(op)
  452. #define CPy_TRASHCAN_END(op) Py_TRASHCAN_SAFE_END(op)
  453. #endif
  454. // Tweaked version of _PyArg_Parser in CPython
  455. typedef struct CPyArg_Parser {
  456. const char *format;
  457. const char * const *keywords;
  458. const char *fname;
  459. const char *custom_msg;
  460. int pos; /* number of positional-only arguments */
  461. int min; /* minimal number of arguments */
  462. int max; /* maximal number of positional arguments */
  463. int has_required_kws; /* are there any keyword-only arguments? */
  464. int required_kwonly_start;
  465. int varargs; /* does the function accept *args or **kwargs? */
  466. PyObject *kwtuple; /* tuple of keyword parameter names */
  467. struct CPyArg_Parser *next;
  468. } CPyArg_Parser;
  469. // mypy lets ints silently coerce to floats, so a mypyc runtime float
  470. // might be an int also
  471. static inline bool CPyFloat_Check(PyObject *o) {
  472. return PyFloat_Check(o) || PyLong_Check(o);
  473. }
  474. // TODO: find an unified way to avoid inline functions in non-C back ends that can not
  475. // use inline functions
  476. static inline bool CPy_TypeCheck(PyObject *o, PyObject *type) {
  477. return PyObject_TypeCheck(o, (PyTypeObject *)type);
  478. }
  479. static inline PyObject *CPy_CalculateMetaclass(PyObject *type, PyObject *o) {
  480. return (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)type, o);
  481. }
  482. PyObject *CPy_GetCoro(PyObject *obj);
  483. PyObject *CPyIter_Send(PyObject *iter, PyObject *val);
  484. int CPy_YieldFromErrorHandle(PyObject *iter, PyObject **outp);
  485. PyObject *CPy_FetchStopIterationValue(void);
  486. PyObject *CPyType_FromTemplate(PyObject *template_,
  487. PyObject *orig_bases,
  488. PyObject *modname);
  489. PyObject *CPyType_FromTemplateWarpper(PyObject *template_,
  490. PyObject *orig_bases,
  491. PyObject *modname);
  492. int CPyDataclass_SleightOfHand(PyObject *dataclass_dec, PyObject *tp,
  493. PyObject *dict, PyObject *annotations);
  494. PyObject *CPyPickle_SetState(PyObject *obj, PyObject *state);
  495. PyObject *CPyPickle_GetState(PyObject *obj);
  496. CPyTagged CPyTagged_Id(PyObject *o);
  497. void CPyDebug_Print(const char *msg);
  498. void CPy_Init(void);
  499. int CPyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
  500. const char *, const char *, const char * const *, ...);
  501. int CPyArg_ParseStackAndKeywords(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
  502. CPyArg_Parser *parser, ...);
  503. int CPyArg_ParseStackAndKeywordsNoArgs(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
  504. CPyArg_Parser *parser, ...);
  505. int CPyArg_ParseStackAndKeywordsOneArg(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
  506. CPyArg_Parser *parser, ...);
  507. int CPyArg_ParseStackAndKeywordsSimple(PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames,
  508. CPyArg_Parser *parser, ...);
  509. int CPySequence_CheckUnpackCount(PyObject *sequence, Py_ssize_t expected);
  510. int CPyStatics_Initialize(PyObject **statics,
  511. const char * const *strings,
  512. const char * const *bytestrings,
  513. const char * const *ints,
  514. const double *floats,
  515. const double *complex_numbers,
  516. const int *tuples,
  517. const int *frozensets);
  518. PyObject *CPy_Super(PyObject *builtins, PyObject *self);
  519. PyObject *CPy_CallReverseOpMethod(PyObject *left, PyObject *right, const char *op,
  520. _Py_Identifier *method);
  521. bool CPyImport_ImportMany(PyObject *modules, CPyModule **statics[], PyObject *globals,
  522. PyObject *tb_path, PyObject *tb_function, Py_ssize_t *tb_lines);
  523. PyObject *CPyImport_ImportFromMany(PyObject *mod_id, PyObject *names, PyObject *as_names,
  524. PyObject *globals);
  525. PyObject *CPySingledispatch_RegisterFunction(PyObject *singledispatch_func, PyObject *cls,
  526. PyObject *func);
  527. PyObject *CPy_GetAIter(PyObject *obj);
  528. PyObject *CPy_GetANext(PyObject *aiter);
  529. #ifdef __cplusplus
  530. }
  531. #endif
  532. #endif // CPY_CPY_H