aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Objects/floatobject.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-04-18 12:39:32 +0300
committershadchin <shadchin@yandex-team.ru>2022-04-18 12:39:32 +0300
commitd4be68e361f4258cf0848fc70018dfe37a2acc24 (patch)
tree153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Objects/floatobject.c
parent260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff)
downloadydb-d4be68e361f4258cf0848fc70018dfe37a2acc24.tar.gz
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Objects/floatobject.c')
-rw-r--r--contrib/tools/python3/src/Objects/floatobject.c153
1 files changed, 106 insertions, 47 deletions
diff --git a/contrib/tools/python3/src/Objects/floatobject.c b/contrib/tools/python3/src/Objects/floatobject.c
index 6ac6127ae5..2e02f37f4a 100644
--- a/contrib/tools/python3/src/Objects/floatobject.c
+++ b/contrib/tools/python3/src/Objects/floatobject.c
@@ -4,7 +4,11 @@
for any kind of float exception without losing portability. */
#include "Python.h"
-#include "pycore_dtoa.h"
+#include "pycore_dtoa.h" // _Py_dg_dtoa()
+#include "pycore_interp.h" // _PyInterpreterState.float_state
+#include "pycore_long.h" // _PyLong_GetOne()
+#include "pycore_object.h" // _PyObject_Init()
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include <ctype.h>
#include <float.h>
@@ -16,16 +20,18 @@ class float "PyObject *" "&PyFloat_Type"
#include "clinic/floatobject.c.h"
-/* Special free list
- free_list is a singly-linked list of available PyFloatObjects, linked
- via abuse of their ob_type members.
-*/
-
#ifndef PyFloat_MAXFREELIST
-#define PyFloat_MAXFREELIST 100
+# define PyFloat_MAXFREELIST 100
#endif
-static int numfree = 0;
-static PyFloatObject *free_list = NULL;
+
+
+static struct _Py_float_state *
+get_float_state(void)
+{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ return &interp->float_state;
+}
+
double
PyFloat_GetMax(void)
@@ -59,12 +65,14 @@ static PyStructSequence_Field floatinfo_fields[] = {
"is a normalized float"},
{"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is "
"a normalized"},
- {"dig", "DBL_DIG -- digits"},
+ {"dig", "DBL_DIG -- maximum number of decimal digits that "
+ "can be faithfully represented in a float"},
{"mant_dig", "DBL_MANT_DIG -- mantissa digits"},
{"epsilon", "DBL_EPSILON -- Difference between 1 and the next "
"representable float"},
{"radix", "FLT_RADIX -- radix of exponent"},
- {"rounds", "FLT_ROUNDS -- rounding mode"},
+ {"rounds", "FLT_ROUNDS -- rounding mode used for arithmetic "
+ "operations"},
{0}
};
@@ -115,17 +123,23 @@ PyFloat_GetInfo(void)
PyObject *
PyFloat_FromDouble(double fval)
{
- PyFloatObject *op = free_list;
+ struct _Py_float_state *state = get_float_state();
+ PyFloatObject *op = state->free_list;
if (op != NULL) {
- free_list = (PyFloatObject *) Py_TYPE(op);
- numfree--;
- } else {
- op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject));
- if (!op)
+#ifdef Py_DEBUG
+ // PyFloat_FromDouble() must not be called after _PyFloat_Fini()
+ assert(state->numfree != -1);
+#endif
+ state->free_list = (PyFloatObject *) Py_TYPE(op);
+ state->numfree--;
+ }
+ else {
+ op = PyObject_Malloc(sizeof(PyFloatObject));
+ if (!op) {
return PyErr_NoMemory();
+ }
}
- /* Inline PyObject_New */
- (void)PyObject_INIT(op, &PyFloat_Type);
+ _PyObject_Init((PyObject*)op, &PyFloat_Type);
op->ob_fval = fval;
return (PyObject *) op;
}
@@ -202,7 +216,7 @@ PyFloat_FromString(PyObject *v)
}
else {
PyErr_Format(PyExc_TypeError,
- "float() argument must be a string or a number, not '%.200s'",
+ "float() argument must be a string or a real number, not '%.200s'",
Py_TYPE(v)->tp_name);
return NULL;
}
@@ -217,16 +231,22 @@ static void
float_dealloc(PyFloatObject *op)
{
if (PyFloat_CheckExact(op)) {
- if (numfree >= PyFloat_MAXFREELIST) {
- PyObject_FREE(op);
+ struct _Py_float_state *state = get_float_state();
+#ifdef Py_DEBUG
+ // float_dealloc() must not be called after _PyFloat_Fini()
+ assert(state->numfree != -1);
+#endif
+ if (state->numfree >= PyFloat_MAXFREELIST) {
+ PyObject_Free(op);
return;
}
- numfree++;
- Py_SET_TYPE(op, (PyTypeObject *)free_list);
- free_list = op;
+ state->numfree++;
+ Py_SET_TYPE(op, (PyTypeObject *)state->free_list);
+ state->free_list = op;
}
- else
+ else {
Py_TYPE(op)->tp_free((PyObject *)op);
+ }
}
double
@@ -248,7 +268,7 @@ PyFloat_AsDouble(PyObject *op)
nb = Py_TYPE(op)->tp_as_number;
if (nb == NULL || nb->nb_float == NULL) {
if (nb && nb->nb_index) {
- PyObject *res = PyNumber_Index(op);
+ PyObject *res = _PyNumber_Index(op);
if (!res) {
return -1;
}
@@ -485,7 +505,7 @@ float_richcompare(PyObject *v, PyObject *w, int op)
Py_DECREF(vv);
vv = temp;
- temp = PyNumber_Or(vv, _PyLong_One);
+ temp = PyNumber_Or(vv, _PyLong_GetOne());
if (temp == NULL)
goto Error;
Py_DECREF(vv);
@@ -536,7 +556,7 @@ float_richcompare(PyObject *v, PyObject *w, int op)
static Py_hash_t
float_hash(PyFloatObject *v)
{
- return _Py_HashDouble(v->ob_fval);
+ return _Py_HashDouble((PyObject *)v, v->ob_fval);
}
static PyObject *
@@ -1586,7 +1606,7 @@ float_subtype_new(PyTypeObject *type, PyObject *x);
/*[clinic input]
@classmethod
float.__new__ as float_new
- x: object(c_default="_PyLong_Zero") = 0
+ x: object(c_default="NULL") = 0
/
Convert a string or number to a floating point number, if possible.
@@ -1594,10 +1614,18 @@ Convert a string or number to a floating point number, if possible.
static PyObject *
float_new_impl(PyTypeObject *type, PyObject *x)
-/*[clinic end generated code: output=ccf1e8dc460ba6ba input=540ee77c204ff87a]*/
+/*[clinic end generated code: output=ccf1e8dc460ba6ba input=f43661b7de03e9d8]*/
{
- if (type != &PyFloat_Type)
+ if (type != &PyFloat_Type) {
+ if (x == NULL) {
+ x = _PyLong_GetZero();
+ }
return float_subtype_new(type, x); /* Wimp out */
+ }
+
+ if (x == NULL) {
+ return PyFloat_FromDouble(0.0);
+ }
/* If it's a string, but not a string subclass, use
PyFloat_FromString. */
if (PyUnicode_CheckExact(x))
@@ -1630,6 +1658,24 @@ float_subtype_new(PyTypeObject *type, PyObject *x)
return newobj;
}
+static PyObject *
+float_vectorcall(PyObject *type, PyObject * const*args,
+ size_t nargsf, PyObject *kwnames)
+{
+ if (!_PyArg_NoKwnames("float", kwnames)) {
+ return NULL;
+ }
+
+ Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+ if (!_PyArg_CheckPositional("float", nargs, 0, 1)) {
+ return NULL;
+ }
+
+ PyObject *x = nargs >= 1 ? args[0] : NULL;
+ return float_new_impl((PyTypeObject *)type, x);
+}
+
+
/*[clinic input]
float.__getnewargs__
[clinic start generated code]*/
@@ -1899,7 +1945,8 @@ PyTypeObject PyFloat_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
+ _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
float_new__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
@@ -1918,9 +1965,10 @@ PyTypeObject PyFloat_Type = {
0, /* tp_init */
0, /* tp_alloc */
float_new, /* tp_new */
+ .tp_vectorcall = (vectorcallfunc)float_vectorcall,
};
-int
+void
_PyFloat_Init(void)
{
/* We attempt to determine if this machine is using IEEE
@@ -1968,41 +2016,52 @@ _PyFloat_Init(void)
double_format = detected_double_format;
float_format = detected_float_format;
+}
+int
+_PyFloat_InitTypes(void)
+{
/* Init float info */
if (FloatInfoType.tp_name == NULL) {
if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) {
- return 0;
+ return -1;
}
}
- return 1;
+ return 0;
}
void
-_PyFloat_ClearFreeList(void)
+_PyFloat_ClearFreeList(PyInterpreterState *interp)
{
- PyFloatObject *f = free_list, *next;
- for (; f; f = next) {
- next = (PyFloatObject*) Py_TYPE(f);
- PyObject_FREE(f);
- }
- free_list = NULL;
- numfree = 0;
+ struct _Py_float_state *state = &interp->float_state;
+ PyFloatObject *f = state->free_list;
+ while (f != NULL) {
+ PyFloatObject *next = (PyFloatObject*) Py_TYPE(f);
+ PyObject_Free(f);
+ f = next;
+ }
+ state->free_list = NULL;
+ state->numfree = 0;
}
void
-_PyFloat_Fini(void)
+_PyFloat_Fini(PyInterpreterState *interp)
{
- _PyFloat_ClearFreeList();
+ _PyFloat_ClearFreeList(interp);
+#ifdef Py_DEBUG
+ struct _Py_float_state *state = &interp->float_state;
+ state->numfree = -1;
+#endif
}
/* Print summary info about the state of the optimized allocator */
void
_PyFloat_DebugMallocStats(FILE *out)
{
+ struct _Py_float_state *state = get_float_state();
_PyDebugAllocatorStats(out,
"free PyFloatObject",
- numfree, sizeof(PyFloatObject));
+ state->numfree, sizeof(PyFloatObject));
}