@@ -266,6 +266,32 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
266266 } while (d != 0 );
267267}
268268
269+ static void
270+ w_float_bin (double v , WFILE * p )
271+ {
272+ unsigned char buf [8 ];
273+ if (_PyFloat_Pack8 (v , buf , 1 ) < 0 ) {
274+ p -> error = WFERR_UNMARSHALLABLE ;
275+ return ;
276+ }
277+ w_string ((const char * )buf , 8 , p );
278+ }
279+
280+ static void
281+ w_float_str (double v , WFILE * p )
282+ {
283+ int n ;
284+ char * buf = PyOS_double_to_string (v , 'g' , 17 , 0 , NULL );
285+ if (!buf ) {
286+ p -> error = WFERR_NOMEMORY ;
287+ return ;
288+ }
289+ n = (int )strlen (buf );
290+ w_byte (n , p );
291+ w_string (buf , n , p );
292+ PyMem_Free (buf );
293+ }
294+
269295static int
270296w_ref (PyObject * v , char * flag , WFILE * p )
271297{
@@ -375,69 +401,24 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
375401 }
376402 else if (PyFloat_CheckExact (v )) {
377403 if (p -> version > 1 ) {
378- unsigned char buf [8 ];
379- if (_PyFloat_Pack8 (PyFloat_AsDouble (v ),
380- buf , 1 ) < 0 ) {
381- p -> error = WFERR_UNMARSHALLABLE ;
382- return ;
383- }
384404 W_TYPE (TYPE_BINARY_FLOAT , p );
385- w_string (( char * ) buf , 8 , p );
405+ w_float_bin ( PyFloat_AS_DOUBLE ( v ) , p );
386406 }
387407 else {
388- char * buf = PyOS_double_to_string (PyFloat_AS_DOUBLE (v ),
389- 'g' , 17 , 0 , NULL );
390- if (!buf ) {
391- p -> error = WFERR_NOMEMORY ;
392- return ;
393- }
394- n = strlen (buf );
395408 W_TYPE (TYPE_FLOAT , p );
396- w_byte ((int )n , p );
397- w_string (buf , n , p );
398- PyMem_Free (buf );
409+ w_float_str (PyFloat_AS_DOUBLE (v ), p );
399410 }
400411 }
401412 else if (PyComplex_CheckExact (v )) {
402413 if (p -> version > 1 ) {
403- unsigned char buf [8 ];
404- if (_PyFloat_Pack8 (PyComplex_RealAsDouble (v ),
405- buf , 1 ) < 0 ) {
406- p -> error = WFERR_UNMARSHALLABLE ;
407- return ;
408- }
409414 W_TYPE (TYPE_BINARY_COMPLEX , p );
410- w_string ((char * )buf , 8 , p );
411- if (_PyFloat_Pack8 (PyComplex_ImagAsDouble (v ),
412- buf , 1 ) < 0 ) {
413- p -> error = WFERR_UNMARSHALLABLE ;
414- return ;
415- }
416- w_string ((char * )buf , 8 , p );
415+ w_float_bin (PyComplex_RealAsDouble (v ), p );
416+ w_float_bin (PyComplex_ImagAsDouble (v ), p );
417417 }
418418 else {
419- char * buf ;
420419 W_TYPE (TYPE_COMPLEX , p );
421- buf = PyOS_double_to_string (PyComplex_RealAsDouble (v ),
422- 'g' , 17 , 0 , NULL );
423- if (!buf ) {
424- p -> error = WFERR_NOMEMORY ;
425- return ;
426- }
427- n = strlen (buf );
428- w_byte ((int )n , p );
429- w_string (buf , n , p );
430- PyMem_Free (buf );
431- buf = PyOS_double_to_string (PyComplex_ImagAsDouble (v ),
432- 'g' , 17 , 0 , NULL );
433- if (!buf ) {
434- p -> error = WFERR_NOMEMORY ;
435- return ;
436- }
437- n = strlen (buf );
438- w_byte ((int )n , p );
439- w_string (buf , n , p );
440- PyMem_Free (buf );
420+ w_float_str (PyComplex_RealAsDouble (v ), p );
421+ w_float_str (PyComplex_ImagAsDouble (v ), p );
441422 }
442423 }
443424 else if (PyBytes_CheckExact (v )) {
@@ -880,6 +861,38 @@ r_PyLong(RFILE *p)
880861 return NULL ;
881862}
882863
864+ static double
865+ r_float_bin (RFILE * p )
866+ {
867+ const unsigned char * buf = (const unsigned char * ) r_string (8 , p );
868+ if (buf == NULL )
869+ return -1 ;
870+ return _PyFloat_Unpack8 (buf , 1 );
871+ }
872+
873+ /* Issue #33720: Disable inlining for reducing the C stack consumption
874+ on PGO builds. */
875+ _Py_NO_INLINE static double
876+ r_float_str (RFILE * p )
877+ {
878+ int n ;
879+ char buf [256 ];
880+ const char * ptr ;
881+ n = r_byte (p );
882+ if (n == EOF ) {
883+ PyErr_SetString (PyExc_EOFError ,
884+ "EOF read where object expected" );
885+ return -1 ;
886+ }
887+ ptr = r_string (n , p );
888+ if (ptr == NULL ) {
889+ return -1 ;
890+ }
891+ memcpy (buf , ptr , n );
892+ buf [n ] = '\0' ;
893+ return PyOS_string_to_double (buf , NULL , NULL );
894+ }
895+
883896/* allocate the reflist index for a new object. Return -1 on failure */
884897static Py_ssize_t
885898r_ref_reserve (int flag , RFILE * p )
@@ -1016,36 +1029,17 @@ r_object(RFILE *p)
10161029
10171030 case TYPE_FLOAT :
10181031 {
1019- char buf [256 ];
1020- const char * ptr ;
1021- double dx ;
1022- n = r_byte (p );
1023- if (n == EOF ) {
1024- PyErr_SetString (PyExc_EOFError ,
1025- "EOF read where object expected" );
1026- break ;
1027- }
1028- ptr = r_string (n , p );
1029- if (ptr == NULL )
1030- break ;
1031- memcpy (buf , ptr , n );
1032- buf [n ] = '\0' ;
1033- dx = PyOS_string_to_double (buf , NULL , NULL );
1034- if (dx == -1.0 && PyErr_Occurred ())
1032+ double x = r_float_str (p );
1033+ if (x == -1.0 && PyErr_Occurred ())
10351034 break ;
1036- retval = PyFloat_FromDouble (dx );
1035+ retval = PyFloat_FromDouble (x );
10371036 R_REF (retval );
10381037 break ;
10391038 }
10401039
10411040 case TYPE_BINARY_FLOAT :
10421041 {
1043- const unsigned char * buf ;
1044- double x ;
1045- buf = (const unsigned char * ) r_string (8 , p );
1046- if (buf == NULL )
1047- break ;
1048- x = _PyFloat_Unpack8 (buf , 1 );
1042+ double x = r_float_bin (p );
10491043 if (x == -1.0 && PyErr_Occurred ())
10501044 break ;
10511045 retval = PyFloat_FromDouble (x );
@@ -1055,35 +1049,11 @@ r_object(RFILE *p)
10551049
10561050 case TYPE_COMPLEX :
10571051 {
1058- char buf [256 ];
1059- const char * ptr ;
10601052 Py_complex c ;
1061- n = r_byte (p );
1062- if (n == EOF ) {
1063- PyErr_SetString (PyExc_EOFError ,
1064- "EOF read where object expected" );
1065- break ;
1066- }
1067- ptr = r_string (n , p );
1068- if (ptr == NULL )
1069- break ;
1070- memcpy (buf , ptr , n );
1071- buf [n ] = '\0' ;
1072- c .real = PyOS_string_to_double (buf , NULL , NULL );
1053+ c .real = r_float_str (p );
10731054 if (c .real == -1.0 && PyErr_Occurred ())
10741055 break ;
1075- n = r_byte (p );
1076- if (n == EOF ) {
1077- PyErr_SetString (PyExc_EOFError ,
1078- "EOF read where object expected" );
1079- break ;
1080- }
1081- ptr = r_string (n , p );
1082- if (ptr == NULL )
1083- break ;
1084- memcpy (buf , ptr , n );
1085- buf [n ] = '\0' ;
1086- c .imag = PyOS_string_to_double (buf , NULL , NULL );
1056+ c .imag = r_float_str (p );
10871057 if (c .imag == -1.0 && PyErr_Occurred ())
10881058 break ;
10891059 retval = PyComplex_FromCComplex (c );
@@ -1093,18 +1063,11 @@ r_object(RFILE *p)
10931063
10941064 case TYPE_BINARY_COMPLEX :
10951065 {
1096- const unsigned char * buf ;
10971066 Py_complex c ;
1098- buf = (const unsigned char * ) r_string (8 , p );
1099- if (buf == NULL )
1100- break ;
1101- c .real = _PyFloat_Unpack8 (buf , 1 );
1067+ c .real = r_float_bin (p );
11021068 if (c .real == -1.0 && PyErr_Occurred ())
11031069 break ;
1104- buf = (const unsigned char * ) r_string (8 , p );
1105- if (buf == NULL )
1106- break ;
1107- c .imag = _PyFloat_Unpack8 (buf , 1 );
1070+ c .imag = r_float_bin (p );
11081071 if (c .imag == -1.0 && PyErr_Occurred ())
11091072 break ;
11101073 retval = PyComplex_FromCComplex (c );
0 commit comments