@@ -266,6 +266,32 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p)
266
266
} while (d != 0 );
267
267
}
268
268
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
+
269
295
static int
270
296
w_ref (PyObject * v , char * flag , WFILE * p )
271
297
{
@@ -375,69 +401,24 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
375
401
}
376
402
else if (PyFloat_CheckExact (v )) {
377
403
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
- }
384
404
W_TYPE (TYPE_BINARY_FLOAT , p );
385
- w_string (( char * ) buf , 8 , p );
405
+ w_float_bin ( PyFloat_AS_DOUBLE ( v ) , p );
386
406
}
387
407
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 );
395
408
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 );
399
410
}
400
411
}
401
412
else if (PyComplex_CheckExact (v )) {
402
413
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
- }
409
414
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 );
417
417
}
418
418
else {
419
- char * buf ;
420
419
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 );
441
422
}
442
423
}
443
424
else if (PyBytes_CheckExact (v )) {
@@ -880,6 +861,38 @@ r_PyLong(RFILE *p)
880
861
return NULL ;
881
862
}
882
863
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
+
883
896
/* allocate the reflist index for a new object. Return -1 on failure */
884
897
static Py_ssize_t
885
898
r_ref_reserve (int flag , RFILE * p )
@@ -1016,36 +1029,17 @@ r_object(RFILE *p)
1016
1029
1017
1030
case TYPE_FLOAT :
1018
1031
{
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 ())
1035
1034
break ;
1036
- retval = PyFloat_FromDouble (dx );
1035
+ retval = PyFloat_FromDouble (x );
1037
1036
R_REF (retval );
1038
1037
break ;
1039
1038
}
1040
1039
1041
1040
case TYPE_BINARY_FLOAT :
1042
1041
{
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 );
1049
1043
if (x == -1.0 && PyErr_Occurred ())
1050
1044
break ;
1051
1045
retval = PyFloat_FromDouble (x );
@@ -1055,35 +1049,11 @@ r_object(RFILE *p)
1055
1049
1056
1050
case TYPE_COMPLEX :
1057
1051
{
1058
- char buf [256 ];
1059
- const char * ptr ;
1060
1052
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 );
1073
1054
if (c .real == -1.0 && PyErr_Occurred ())
1074
1055
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 );
1087
1057
if (c .imag == -1.0 && PyErr_Occurred ())
1088
1058
break ;
1089
1059
retval = PyComplex_FromCComplex (c );
@@ -1093,18 +1063,11 @@ r_object(RFILE *p)
1093
1063
1094
1064
case TYPE_BINARY_COMPLEX :
1095
1065
{
1096
- const unsigned char * buf ;
1097
1066
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 );
1102
1068
if (c .real == -1.0 && PyErr_Occurred ())
1103
1069
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 );
1108
1071
if (c .imag == -1.0 && PyErr_Occurred ())
1109
1072
break ;
1110
1073
retval = PyComplex_FromCComplex (c );
0 commit comments