Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Include/internal/pycore_long.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ extern "C" {

/* runtime lifecycle */

extern PyStatus _PyLong_InitRuntime(void);
extern PyStatus _PyLong_InitTypes(PyInterpreterState *);
extern void _PyLong_FiniTypes(PyInterpreterState *interp);

Expand Down
47 changes: 32 additions & 15 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2820,23 +2820,18 @@ that triggers it(!). Instead the code was tested by artificially allocating
just 1 digit at the start, so that the copying code was exercised for every
digit beyond the first.
***/
static int
long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res)
{
twodigits c; /* current input character */
Py_ssize_t size_z;
int i;
int convwidth;
twodigits convmultmax, convmult;
digit *pz, *pzstop;
PyLongObject *z;
const char *p;

static double log_base_BASE[37] = {0.0e0,};
static int convwidth_base[37] = {0,};
static twodigits convmultmax_base[37] = {0,};
static double log_base_BASE[37] = {0.0e0,};
static int convwidth_base[37] = {0,};
static twodigits convmultmax_base[37] = {0,};

if (log_base_BASE[base] == 0.0) {
static void
long_precompute_base_conv(void)
{
// These constants are quick to compute (likely less than 1 μs) and
// computing them at runtime avoids hard-coding a table dependant on
// PyLong_BASE.
for (int base = 2; base <= 36; base++) {
twodigits convmax = base;
int i = 1;

Expand All @@ -2854,6 +2849,21 @@ long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits,
assert(i > 0);
convwidth_base[base] = i;
}
}

static int
long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res)
{
twodigits c; /* current input character */
Py_ssize_t size_z;
int i;
int convwidth;
twodigits convmultmax, convmult;
digit *pz, *pzstop;
PyLongObject *z;
const char *p;

assert (log_base_BASE[base] != 0.0); // pre-computed by _PyLong_InitRuntime()

/* Create an int object that can contain the largest possible
* integer with this base and length. Note that there's no
Expand Down Expand Up @@ -6740,6 +6750,13 @@ PyLong_GetInfo(void)

/* runtime lifecycle */

PyStatus
_PyLong_InitRuntime(void)
{
long_precompute_base_conv();
return _PyStatus_OK();
}

PyStatus
_PyLong_InitTypes(PyInterpreterState *interp)
{
Expand Down
5 changes: 5 additions & 0 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,11 @@ pycore_init_runtime(_PyRuntimeState *runtime,
return status;
}

status = _PyLong_InitRuntime();
if (_PyStatus_EXCEPTION(status)) {
return status;
}

status = _PyImport_Init();
if (_PyStatus_EXCEPTION(status)) {
return status;
Expand Down
Loading