LCOV - code coverage report
Current view: top level - Include/internal - pycore_long.h (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 9 9 100.0 %
Date: 2023-03-20 08:15:36 Functions: 4 4 100.0 %
Branches: 0 0 -

           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 */

Generated by: LCOV version 1.14