@@ -2820,23 +2820,18 @@ that triggers it(!). Instead the code was tested by artificially allocating
28202820just 1 digit at the start, so that the copying code was exercised for every
28212821digit beyond the first.
28222822***/
2823- static int
2824- long_from_non_binary_base (const char * start , const char * end , Py_ssize_t digits , int base , PyLongObject * * res )
2825- {
2826- twodigits c ; /* current input character */
2827- Py_ssize_t size_z ;
2828- int i ;
2829- int convwidth ;
2830- twodigits convmultmax , convmult ;
2831- digit * pz , * pzstop ;
2832- PyLongObject * z ;
2833- const char * p ;
28342823
2835- static double log_base_BASE [37 ] = {0.0e0 ,};
2836- static int convwidth_base [37 ] = {0 ,};
2837- static twodigits convmultmax_base [37 ] = {0 ,};
2824+ static double log_base_BASE [37 ] = {0.0e0 ,};
2825+ static int convwidth_base [37 ] = {0 ,};
2826+ static twodigits convmultmax_base [37 ] = {0 ,};
28382827
2839- if (log_base_BASE [base ] == 0.0 ) {
2828+ static void
2829+ long_precompute_base_conv (void )
2830+ {
2831+ // These constants are quick to compute (likely less than 1 μs) and
2832+ // computing them at runtime avoids hard-coding a table dependant on
2833+ // PyLong_BASE.
2834+ for (int base = 2 ; base <= 36 ; base ++ ) {
28402835 twodigits convmax = base ;
28412836 int i = 1 ;
28422837
@@ -2854,6 +2849,21 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits,
28542849 assert (i > 0 );
28552850 convwidth_base [base ] = i ;
28562851 }
2852+ }
2853+
2854+ static int
2855+ long_from_non_binary_base (const char * start , const char * end , Py_ssize_t digits , int base , PyLongObject * * res )
2856+ {
2857+ twodigits c ; /* current input character */
2858+ Py_ssize_t size_z ;
2859+ int i ;
2860+ int convwidth ;
2861+ twodigits convmultmax , convmult ;
2862+ digit * pz , * pzstop ;
2863+ PyLongObject * z ;
2864+ const char * p ;
2865+
2866+ assert (log_base_BASE [base ] != 0.0 ); // pre-computed by _PyLong_InitRuntime()
28572867
28582868 /* Create an int object that can contain the largest possible
28592869 * integer with this base and length. Note that there's no
@@ -6740,6 +6750,13 @@ PyLong_GetInfo(void)
67406750
67416751/* runtime lifecycle */
67426752
6753+ PyStatus
6754+ _PyLong_InitRuntime (void )
6755+ {
6756+ long_precompute_base_conv ();
6757+ return _PyStatus_OK ();
6758+ }
6759+
67436760PyStatus
67446761_PyLong_InitTypes (PyInterpreterState * interp )
67456762{
0 commit comments