pythonsupport.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. // Collects code that was copied in from cpython, for a couple of different reasons:
  2. // * We wanted to modify it to produce a more efficient version for our uses
  3. // * We needed to call it and it was static :(
  4. // * We wanted to call it and needed to backport it
  5. #ifndef CPY_PYTHONSUPPORT_H
  6. #define CPY_PYTHONSUPPORT_H
  7. #include <stdbool.h>
  8. #include <Python.h>
  9. #include "pythoncapi_compat.h"
  10. #include <frameobject.h>
  11. #include <assert.h>
  12. #include "mypyc_util.h"
  13. #if CPY_3_12_FEATURES
  14. #include "internal/pycore_frame.h"
  15. #endif
  16. #ifdef __cplusplus
  17. extern "C" {
  18. #endif
  19. #if 0
  20. } // why isn't emacs smart enough to not indent this
  21. #endif
  22. /////////////////////////////////////////
  23. // Adapted from bltinmodule.c in Python 3.7.0
  24. _Py_IDENTIFIER(__mro_entries__);
  25. static PyObject*
  26. update_bases(PyObject *bases)
  27. {
  28. Py_ssize_t i, j;
  29. PyObject *base, *meth, *new_base, *result, *new_bases = NULL;
  30. PyObject *stack[1] = {bases};
  31. assert(PyTuple_Check(bases));
  32. Py_ssize_t nargs = PyTuple_GET_SIZE(bases);
  33. for (i = 0; i < nargs; i++) {
  34. base = PyTuple_GET_ITEM(bases, i);
  35. if (PyType_Check(base)) {
  36. if (new_bases) {
  37. /* If we already have made a replacement, then we append every normal base,
  38. otherwise just skip it. */
  39. if (PyList_Append(new_bases, base) < 0) {
  40. goto error;
  41. }
  42. }
  43. continue;
  44. }
  45. if (_PyObject_LookupAttrId(base, &PyId___mro_entries__, &meth) < 0) {
  46. goto error;
  47. }
  48. if (!meth) {
  49. if (new_bases) {
  50. if (PyList_Append(new_bases, base) < 0) {
  51. goto error;
  52. }
  53. }
  54. continue;
  55. }
  56. new_base = _PyObject_FastCall(meth, stack, 1);
  57. Py_DECREF(meth);
  58. if (!new_base) {
  59. goto error;
  60. }
  61. if (!PyTuple_Check(new_base)) {
  62. PyErr_SetString(PyExc_TypeError,
  63. "__mro_entries__ must return a tuple");
  64. Py_DECREF(new_base);
  65. goto error;
  66. }
  67. if (!new_bases) {
  68. /* If this is a first successful replacement, create new_bases list and
  69. copy previously encountered bases. */
  70. if (!(new_bases = PyList_New(i))) {
  71. goto error;
  72. }
  73. for (j = 0; j < i; j++) {
  74. base = PyTuple_GET_ITEM(bases, j);
  75. PyList_SET_ITEM(new_bases, j, base);
  76. Py_INCREF(base);
  77. }
  78. }
  79. j = PyList_GET_SIZE(new_bases);
  80. if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
  81. goto error;
  82. }
  83. Py_DECREF(new_base);
  84. }
  85. if (!new_bases) {
  86. return bases;
  87. }
  88. result = PyList_AsTuple(new_bases);
  89. Py_DECREF(new_bases);
  90. return result;
  91. error:
  92. Py_XDECREF(new_bases);
  93. return NULL;
  94. }
  95. // From Python 3.7's typeobject.c
  96. _Py_IDENTIFIER(__init_subclass__);
  97. static int
  98. init_subclass(PyTypeObject *type, PyObject *kwds)
  99. {
  100. PyObject *super, *func, *result;
  101. PyObject *args[2] = {(PyObject *)type, (PyObject *)type};
  102. super = _PyObject_FastCall((PyObject *)&PySuper_Type, args, 2);
  103. if (super == NULL) {
  104. return -1;
  105. }
  106. func = _PyObject_GetAttrId(super, &PyId___init_subclass__);
  107. Py_DECREF(super);
  108. if (func == NULL) {
  109. return -1;
  110. }
  111. result = _PyObject_FastCallDict(func, NULL, 0, kwds);
  112. Py_DECREF(func);
  113. if (result == NULL) {
  114. return -1;
  115. }
  116. Py_DECREF(result);
  117. return 0;
  118. }
  119. #if CPY_3_12_FEATURES
  120. static inline Py_ssize_t
  121. CPyLong_AsSsize_tAndOverflow(PyObject *vv, int *overflow)
  122. {
  123. /* This version by Tim Peters */
  124. PyLongObject *v = (PyLongObject *)vv;
  125. size_t x, prev;
  126. Py_ssize_t res;
  127. Py_ssize_t i;
  128. int sign;
  129. *overflow = 0;
  130. res = -1;
  131. i = CPY_LONG_TAG(v);
  132. // TODO: Combine zero and non-zero cases helow?
  133. if (likely(i == (1 << CPY_NON_SIZE_BITS))) {
  134. res = CPY_LONG_DIGIT(v, 0);
  135. } else if (likely(i == CPY_SIGN_ZERO)) {
  136. res = 0;
  137. } else if (i == ((1 << CPY_NON_SIZE_BITS) | CPY_SIGN_NEGATIVE)) {
  138. res = -(sdigit)CPY_LONG_DIGIT(v, 0);
  139. } else {
  140. sign = 1;
  141. x = 0;
  142. if (i & CPY_SIGN_NEGATIVE) {
  143. sign = -1;
  144. }
  145. i >>= CPY_NON_SIZE_BITS;
  146. while (--i >= 0) {
  147. prev = x;
  148. x = (x << PyLong_SHIFT) + CPY_LONG_DIGIT(v, i);
  149. if ((x >> PyLong_SHIFT) != prev) {
  150. *overflow = sign;
  151. goto exit;
  152. }
  153. }
  154. /* Haven't lost any bits, but casting to long requires extra
  155. * care (see comment above).
  156. */
  157. if (x <= (size_t)CPY_TAGGED_MAX) {
  158. res = (Py_ssize_t)x * sign;
  159. }
  160. else if (sign < 0 && x == CPY_TAGGED_ABS_MIN) {
  161. res = CPY_TAGGED_MIN;
  162. }
  163. else {
  164. *overflow = sign;
  165. /* res is already set to -1 */
  166. }
  167. }
  168. exit:
  169. return res;
  170. }
  171. #else
  172. // Adapted from longobject.c in Python 3.7.0
  173. /* This function adapted from PyLong_AsLongLongAndOverflow, but with
  174. * some safety checks removed and specialized to only work for objects
  175. * that are already longs.
  176. * About half of the win this provides, though, just comes from being
  177. * able to inline the function, which in addition to saving function call
  178. * overhead allows the out-parameter overflow flag to be collapsed into
  179. * control flow.
  180. * Additionally, we check against the possible range of CPyTagged, not of
  181. * Py_ssize_t. */
  182. static inline Py_ssize_t
  183. CPyLong_AsSsize_tAndOverflow(PyObject *vv, int *overflow)
  184. {
  185. /* This version by Tim Peters */
  186. PyLongObject *v = (PyLongObject *)vv;
  187. size_t x, prev;
  188. Py_ssize_t res;
  189. Py_ssize_t i;
  190. int sign;
  191. *overflow = 0;
  192. res = -1;
  193. i = Py_SIZE(v);
  194. if (likely(i == 1)) {
  195. res = CPY_LONG_DIGIT(v, 0);
  196. } else if (likely(i == 0)) {
  197. res = 0;
  198. } else if (i == -1) {
  199. res = -(sdigit)CPY_LONG_DIGIT(v, 0);
  200. } else {
  201. sign = 1;
  202. x = 0;
  203. if (i < 0) {
  204. sign = -1;
  205. i = -(i);
  206. }
  207. while (--i >= 0) {
  208. prev = x;
  209. x = (x << PyLong_SHIFT) + CPY_LONG_DIGIT(v, i);
  210. if ((x >> PyLong_SHIFT) != prev) {
  211. *overflow = sign;
  212. goto exit;
  213. }
  214. }
  215. /* Haven't lost any bits, but casting to long requires extra
  216. * care (see comment above).
  217. */
  218. if (x <= (size_t)CPY_TAGGED_MAX) {
  219. res = (Py_ssize_t)x * sign;
  220. }
  221. else if (sign < 0 && x == CPY_TAGGED_ABS_MIN) {
  222. res = CPY_TAGGED_MIN;
  223. }
  224. else {
  225. *overflow = sign;
  226. /* res is already set to -1 */
  227. }
  228. }
  229. exit:
  230. return res;
  231. }
  232. #endif
  233. // Adapted from listobject.c in Python 3.7.0
  234. static int
  235. list_resize(PyListObject *self, Py_ssize_t newsize)
  236. {
  237. PyObject **items;
  238. size_t new_allocated, num_allocated_bytes;
  239. Py_ssize_t allocated = self->allocated;
  240. /* Bypass realloc() when a previous overallocation is large enough
  241. to accommodate the newsize. If the newsize falls lower than half
  242. the allocated size, then proceed with the realloc() to shrink the list.
  243. */
  244. if (allocated >= newsize && newsize >= (allocated >> 1)) {
  245. assert(self->ob_item != NULL || newsize == 0);
  246. Py_SET_SIZE(self, newsize);
  247. return 0;
  248. }
  249. /* This over-allocates proportional to the list size, making room
  250. * for additional growth. The over-allocation is mild, but is
  251. * enough to give linear-time amortized behavior over a long
  252. * sequence of appends() in the presence of a poorly-performing
  253. * system realloc().
  254. * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
  255. * Note: new_allocated won't overflow because the largest possible value
  256. * is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
  257. */
  258. new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6);
  259. if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) {
  260. PyErr_NoMemory();
  261. return -1;
  262. }
  263. if (newsize == 0)
  264. new_allocated = 0;
  265. num_allocated_bytes = new_allocated * sizeof(PyObject *);
  266. items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);
  267. if (items == NULL) {
  268. PyErr_NoMemory();
  269. return -1;
  270. }
  271. self->ob_item = items;
  272. Py_SET_SIZE(self, newsize);
  273. self->allocated = new_allocated;
  274. return 0;
  275. }
  276. // Changed to use PyList_SetSlice instead of the internal list_ass_slice
  277. static PyObject *
  278. list_pop_impl(PyListObject *self, Py_ssize_t index)
  279. {
  280. PyObject *v;
  281. int status;
  282. if (Py_SIZE(self) == 0) {
  283. /* Special-case most common failure cause */
  284. PyErr_SetString(PyExc_IndexError, "pop from empty list");
  285. return NULL;
  286. }
  287. if (index < 0)
  288. index += Py_SIZE(self);
  289. if (index < 0 || index >= Py_SIZE(self)) {
  290. PyErr_SetString(PyExc_IndexError, "pop index out of range");
  291. return NULL;
  292. }
  293. v = self->ob_item[index];
  294. if (index == Py_SIZE(self) - 1) {
  295. status = list_resize(self, Py_SIZE(self) - 1);
  296. if (status >= 0)
  297. return v; /* and v now owns the reference the list had */
  298. else
  299. return NULL;
  300. }
  301. Py_INCREF(v);
  302. status = PyList_SetSlice((PyObject *)self, index, index+1, (PyObject *)NULL);
  303. if (status < 0) {
  304. Py_DECREF(v);
  305. return NULL;
  306. }
  307. return v;
  308. }
  309. // Tweaked to directly use CPyTagged
  310. static CPyTagged
  311. list_count(PyListObject *self, PyObject *value)
  312. {
  313. Py_ssize_t count = 0;
  314. Py_ssize_t i;
  315. for (i = 0; i < Py_SIZE(self); i++) {
  316. int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
  317. if (cmp > 0)
  318. count++;
  319. else if (cmp < 0)
  320. return CPY_INT_TAG;
  321. }
  322. return CPyTagged_ShortFromSsize_t(count);
  323. }
  324. #if PY_VERSION_HEX < 0x03080000
  325. static PyObject *
  326. _PyDict_GetItemStringWithError(PyObject *v, const char *key)
  327. {
  328. PyObject *kv, *rv;
  329. kv = PyUnicode_FromString(key);
  330. if (kv == NULL) {
  331. return NULL;
  332. }
  333. rv = PyDict_GetItemWithError(v, kv);
  334. Py_DECREF(kv);
  335. return rv;
  336. }
  337. #endif
  338. #define CPyUnicode_EqualToASCIIString(x, y) _PyUnicode_EqualToASCIIString(x, y)
  339. // Adapted from genobject.c in Python 3.7.2
  340. // Copied because it wasn't in 3.5.2 and it is undocumented anyways.
  341. /*
  342. * Set StopIteration with specified value. Value can be arbitrary object
  343. * or NULL.
  344. *
  345. * Returns 0 if StopIteration is set and -1 if any other exception is set.
  346. */
  347. static int
  348. CPyGen_SetStopIterationValue(PyObject *value)
  349. {
  350. PyObject *e;
  351. if (value == NULL ||
  352. (!PyTuple_Check(value) && !PyExceptionInstance_Check(value)))
  353. {
  354. /* Delay exception instantiation if we can */
  355. PyErr_SetObject(PyExc_StopIteration, value);
  356. return 0;
  357. }
  358. /* Construct an exception instance manually with
  359. * PyObject_CallOneArg and pass it to PyErr_SetObject.
  360. *
  361. * We do this to handle a situation when "value" is a tuple, in which
  362. * case PyErr_SetObject would set the value of StopIteration to
  363. * the first element of the tuple.
  364. *
  365. * (See PyErr_SetObject/_PyErr_CreateException code for details.)
  366. */
  367. e = PyObject_CallOneArg(PyExc_StopIteration, value);
  368. if (e == NULL) {
  369. return -1;
  370. }
  371. PyErr_SetObject(PyExc_StopIteration, e);
  372. Py_DECREF(e);
  373. return 0;
  374. }
  375. // Copied from dictobject.c and dictobject.h, these are not Public before
  376. // Python 3.8. Also remove some error checks that we do in the callers.
  377. typedef struct {
  378. PyObject_HEAD
  379. PyDictObject *dv_dict;
  380. } _CPyDictViewObject;
  381. static PyObject *
  382. _CPyDictView_New(PyObject *dict, PyTypeObject *type)
  383. {
  384. _CPyDictViewObject *dv = PyObject_GC_New(_CPyDictViewObject, type);
  385. if (dv == NULL)
  386. return NULL;
  387. Py_INCREF(dict);
  388. dv->dv_dict = (PyDictObject *)dict;
  389. PyObject_GC_Track(dv);
  390. return (PyObject *)dv;
  391. }
  392. #ifdef __cplusplus
  393. }
  394. #endif
  395. #if PY_VERSION_HEX >= 0x030A0000 // 3.10
  396. static int
  397. _CPyObject_HasAttrId(PyObject *v, _Py_Identifier *name) {
  398. PyObject *tmp = NULL;
  399. int result = _PyObject_LookupAttrId(v, name, &tmp);
  400. if (tmp) {
  401. Py_DECREF(tmp);
  402. }
  403. return result;
  404. }
  405. #else
  406. #define _CPyObject_HasAttrId _PyObject_HasAttrId
  407. #endif
  408. #if PY_VERSION_HEX < 0x03090000
  409. // OneArgs and NoArgs functions got added in 3.9
  410. #define _PyObject_CallMethodIdNoArgs(self, name) \
  411. _PyObject_CallMethodIdObjArgs((self), (name), NULL)
  412. #define _PyObject_CallMethodIdOneArg(self, name, arg) \
  413. _PyObject_CallMethodIdObjArgs((self), (name), (arg), NULL)
  414. #endif
  415. #if CPY_3_12_FEATURES
  416. // These are copied from genobject.c in Python 3.12
  417. /* Returns a borrowed reference */
  418. static inline PyCodeObject *
  419. _PyGen_GetCode(PyGenObject *gen) {
  420. _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe);
  421. return frame->f_code;
  422. }
  423. static int
  424. gen_is_coroutine(PyObject *o)
  425. {
  426. if (PyGen_CheckExact(o)) {
  427. PyCodeObject *code = _PyGen_GetCode((PyGenObject*)o);
  428. if (code->co_flags & CO_ITERABLE_COROUTINE) {
  429. return 1;
  430. }
  431. }
  432. return 0;
  433. }
  434. #else
  435. // Copied from genobject.c in Python 3.10
  436. static int
  437. gen_is_coroutine(PyObject *o)
  438. {
  439. if (PyGen_CheckExact(o)) {
  440. PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code;
  441. if (code->co_flags & CO_ITERABLE_COROUTINE) {
  442. return 1;
  443. }
  444. }
  445. return 0;
  446. }
  447. #endif
  448. /*
  449. * This helper function returns an awaitable for `o`:
  450. * - `o` if `o` is a coroutine-object;
  451. * - `type(o)->tp_as_async->am_await(o)`
  452. *
  453. * Raises a TypeError if it's not possible to return
  454. * an awaitable and returns NULL.
  455. */
  456. static PyObject *
  457. CPyCoro_GetAwaitableIter(PyObject *o)
  458. {
  459. unaryfunc getter = NULL;
  460. PyTypeObject *ot;
  461. if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) {
  462. /* 'o' is a coroutine. */
  463. Py_INCREF(o);
  464. return o;
  465. }
  466. ot = Py_TYPE(o);
  467. if (ot->tp_as_async != NULL) {
  468. getter = ot->tp_as_async->am_await;
  469. }
  470. if (getter != NULL) {
  471. PyObject *res = (*getter)(o);
  472. if (res != NULL) {
  473. if (PyCoro_CheckExact(res) || gen_is_coroutine(res)) {
  474. /* __await__ must return an *iterator*, not
  475. a coroutine or another awaitable (see PEP 492) */
  476. PyErr_SetString(PyExc_TypeError,
  477. "__await__() returned a coroutine");
  478. Py_CLEAR(res);
  479. } else if (!PyIter_Check(res)) {
  480. PyErr_Format(PyExc_TypeError,
  481. "__await__() returned non-iterator "
  482. "of type '%.100s'",
  483. Py_TYPE(res)->tp_name);
  484. Py_CLEAR(res);
  485. }
  486. }
  487. return res;
  488. }
  489. PyErr_Format(PyExc_TypeError,
  490. "object %.100s can't be used in 'await' expression",
  491. ot->tp_name);
  492. return NULL;
  493. }
  494. #endif