Branch data Line data Source code
1 : : #ifndef Py_INTERNAL_LONG_H 2 : : #define Py_INTERNAL_LONG_H 3 : : #ifdef __cplusplus 4 : : extern "C" { 5 : : #endif 6 : : 7 : : #ifndef Py_BUILD_CORE 8 : : # error "this header requires Py_BUILD_CORE define" 9 : : #endif 10 : : 11 : : #include "pycore_global_objects.h" // _PY_NSMALLNEGINTS 12 : : #include "pycore_runtime.h" // _PyRuntime 13 : : 14 : : /* 15 : : * Default int base conversion size limitation: Denial of Service prevention. 16 : : * 17 : : * Chosen such that this isn't wildly slow on modern hardware and so that 18 : : * everyone's existing deployed numpy test suite passes before 19 : : * https://github.com/numpy/numpy/issues/22098 is widely available. 20 : : * 21 : : * $ python -m timeit -s 's = "1"*4300' 'int(s)' 22 : : * 2000 loops, best of 5: 125 usec per loop 23 : : * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)' 24 : : * 1000 loops, best of 5: 311 usec per loop 25 : : * (zen2 cloud VM) 26 : : * 27 : : * 4300 decimal digits fits a ~14284 bit number. 28 : : */ 29 : : #define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300 30 : : /* 31 : : * Threshold for max digits check. For performance reasons int() and 32 : : * int.__str__() don't checks values that are smaller than this 33 : : * threshold. Acts as a guaranteed minimum size limit for bignums that 34 : : * applications can expect from CPython. 35 : : * 36 : : * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))' 37 : : * 20000 loops, best of 5: 12 usec per loop 38 : : * 39 : : * "640 digits should be enough for anyone." - gps 40 : : * fits a ~2126 bit decimal number. 41 : : */ 42 : : #define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640 43 : : 44 : : #if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \ 45 : : (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) 46 : : # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold." 47 : : #endif 48 : : 49 : : 50 : : /* runtime lifecycle */ 51 : : 52 : : extern PyStatus _PyLong_InitTypes(PyInterpreterState *); 53 : : extern void _PyLong_FiniTypes(PyInterpreterState *interp); 54 : : 55 : : 56 : : /* other API */ 57 : : 58 : : #define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints) 59 : : 60 : : // _PyLong_GetZero() and _PyLong_GetOne() must always be available 61 : : // _PyLong_FromUnsignedChar must always be available 62 : : #if _PY_NSMALLPOSINTS < 257 63 : : # error "_PY_NSMALLPOSINTS must be greater than or equal to 257" 64 : : #endif 65 : : 66 : : // Return a borrowed reference to the zero singleton. 67 : : // The function cannot return NULL. 68 : 16411 : static inline PyObject* _PyLong_GetZero(void) 69 : 16411 : { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; } 70 : : 71 : : // Return a borrowed reference to the one singleton. 72 : : // The function cannot return NULL. 73 : 100731 : static inline PyObject* _PyLong_GetOne(void) 74 : 100731 : { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } 75 : : 76 : 686811 : static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) 77 : : { 78 : 686811 : return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]); 79 : : } 80 : : 81 : : PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right); 82 : : PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right); 83 : : PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right); 84 : : 85 : : int _PyLong_AssignValue(PyObject **target, Py_ssize_t value); 86 : : 87 : : /* Used by Python/mystrtoul.c, _PyBytes_FromHex(), 88 : : _PyBytes_DecodeEscape(), etc. */ 89 : : PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; 90 : : 91 : : /* Format the object based on the format_spec, as defined in PEP 3101 92 : : (Advanced String Formatting). */ 93 : : PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter( 94 : : _PyUnicodeWriter *writer, 95 : : PyObject *obj, 96 : : PyObject *format_spec, 97 : : Py_ssize_t start, 98 : : Py_ssize_t end); 99 : : 100 : : PyAPI_FUNC(int) _PyLong_FormatWriter( 101 : : _PyUnicodeWriter *writer, 102 : : PyObject *obj, 103 : : int base, 104 : : int alternate); 105 : : 106 : : PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( 107 : : _PyBytesWriter *writer, 108 : : char *str, 109 : : PyObject *obj, 110 : : int base, 111 : : int alternate); 112 : : 113 : : /* Return 1 if the argument is positive single digit int */ 114 : : static inline int 115 : 1071107 : _PyLong_IsPositiveSingleDigit(PyObject* sub) { 116 : : /* For a positive single digit int, the value of Py_SIZE(sub) is 0 or 1. 117 : : 118 : : We perform a fast check using a single comparison by casting from int 119 : : to uint which casts negative numbers to large positive numbers. 120 : : For details see Section 14.2 "Bounds Checking" in the Agner Fog 121 : : optimization manual found at: 122 : : https://www.agner.org/optimize/optimizing_cpp.pdf 123 : : 124 : : The function is not affected by -fwrapv, -fno-wrapv and -ftrapv 125 : : compiler options of GCC and clang 126 : : */ 127 : : assert(PyLong_CheckExact(sub)); 128 : 1071107 : Py_ssize_t signed_size = Py_SIZE(sub); 129 : 1071107 : return ((size_t)signed_size) <= 1; 130 : : } 131 : : 132 : : #ifdef __cplusplus 133 : : } 134 : : #endif 135 : : #endif /* !Py_INTERNAL_LONG_H */