Skip to content

Commit 9e1f13d

Browse files
committedSep 1, 2022
Move int_max_str_digits out of PyInterpreterState
Abigail does not like the fact that `PyInterpreterState` has changed size and some fields have been moved around. Even placing `int_max_str_digits` after `_initial_thread` does not make her happy. Let's move the field out ouf the state and make the setting a process-wide global. It's ugly, but better ugly than breaking somebody's code. ``` [C]'function void PyEval_AcquireThread(PyThreadState*)' at ceval.c:452:1 has some indirect sub-type changes: parameter 1 of type 'PyThreadState*' has sub-type changes: in pointed to type 'typedef PyThreadState' at pytypedefs.h:24:1: underlying type 'struct _ts' at pystate.h:82:1 changed: type size hasn't changed 1 data member changes (2 filtered): type of 'PyInterpreterState* _ts::interp' changed: in pointed to type 'typedef PyInterpreterState' at pytypedefs.h:25:1: underlying type 'struct _is' at pycore_interp.h:78:1 changed: type size changed from 861952 to 862016 (in bits) 1 data member insertion: 'int _is::int_max_str_digits', at offset 859072 (in bits) at pycore_interp.h:179:1 2 data member changes (3 filtered): type of 'pyruntimestate* _is::runtime' changed: in pointed to type 'struct pyruntimestate' at pycore_runtime.h:59:1: type size changed from 1333440 to 1333504 (in bits) 1 data member changes (2 filtered): 'PyThreadState _is::_initial_thread' offset changed from 859072 to 859136 (in bits) (by +64 bits) ```
1 parent 58a4f64 commit 9e1f13d

File tree

3 files changed

+13
-12
lines changed

3 files changed

+13
-12
lines changed
 

‎Include/internal/pycore_interp.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,6 @@ struct _is {
176176
struct type_cache type_cache;
177177
struct callable_cache callable_cache;
178178

179-
int int_max_str_digits;
180-
181179
/* The following fields are here to avoid allocation during init.
182180
The data is exposed through PyInterpreterState pointer fields.
183181
These fields should not be accessed directly outside of init.
@@ -194,6 +192,10 @@ struct _is {
194192
PyThreadState _initial_thread;
195193
};
196194

195+
/* The value should be part of PyInterpreterState. However that would change
196+
* the size of the struct and therefore break our ABI promise. Abigail
197+
* does not like it... Oh my! */
198+
extern int _Py_int_max_str_digits;
197199

198200
/* other API */
199201

‎Objects/longobject.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -1786,8 +1786,7 @@ long_to_decimal_string_internal(PyObject *aa,
17861786
strlen++;
17871787
}
17881788
if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
1789-
PyInterpreterState *interp = _PyInterpreterState_GET();
1790-
int max_str_digits = interp->int_max_str_digits;
1789+
int max_str_digits = _Py_int_max_str_digits;
17911790
Py_ssize_t strlen_nosign = strlen - negative;
17921791
if ((max_str_digits > 0) && (strlen_nosign > max_str_digits)) {
17931792
Py_DECREF(scratch);
@@ -2463,8 +2462,7 @@ digit beyond the first.
24632462

24642463
/* Limit the size to avoid excessive computation attacks. */
24652464
if (digits > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
2466-
PyInterpreterState *interp = _PyInterpreterState_GET();
2467-
int max_str_digits = interp->int_max_str_digits;
2465+
int max_str_digits = _Py_int_max_str_digits;
24682466
if ((max_str_digits > 0) && (digits > max_str_digits)) {
24692467
PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT,
24702468
max_str_digits, digits);
@@ -6129,6 +6127,8 @@ PyLong_GetInfo(void)
61296127

61306128
/* runtime lifecycle */
61316129

6130+
int _Py_int_max_str_digits;
6131+
61326132
PyStatus
61336133
_PyLong_InitTypes(PyInterpreterState *interp)
61346134
{
@@ -6146,9 +6146,9 @@ _PyLong_InitTypes(PyInterpreterState *interp)
61466146
return _PyStatus_ERR("can't init int info type");
61476147
}
61486148
}
6149-
interp->int_max_str_digits = _Py_global_config_int_max_str_digits;
6150-
if (interp->int_max_str_digits == -1) {
6151-
interp->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS;
6149+
_Py_int_max_str_digits = _Py_global_config_int_max_str_digits;
6150+
if (_Py_int_max_str_digits == -1) {
6151+
_Py_int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS;
61526152
}
61536153

61546154
return _PyStatus_OK();

‎Python/sysmodule.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -1633,7 +1633,7 @@ sys_get_int_max_str_digits_impl(PyObject *module)
16331633
/*[clinic end generated code: output=0042f5e8ae0e8631 input=8dab13e2023e60d5]*/
16341634
{
16351635
PyInterpreterState *interp = _PyInterpreterState_GET();
1636-
return PyLong_FromSsize_t(interp->int_max_str_digits);
1636+
return PyLong_FromSsize_t(_Py_int_max_str_digits);
16371637
}
16381638

16391639
/*[clinic input]
@@ -1648,9 +1648,8 @@ static PyObject *
16481648
sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
16491649
/*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/
16501650
{
1651-
PyThreadState *tstate = _PyThreadState_GET();
16521651
if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) {
1653-
tstate->interp->int_max_str_digits = maxdigits;
1652+
_Py_int_max_str_digits = maxdigits;
16541653
Py_RETURN_NONE;
16551654
} else {
16561655
PyErr_Format(

0 commit comments

Comments
 (0)
Please sign in to comment.