@@ -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