@@ -171,18 +171,26 @@ _PyLong_New(Py_ssize_t size)
171
171
PyLongObject *
172
172
_PyLong_FromDigits (int negative , Py_ssize_t digit_count , digit * digits )
173
173
{
174
- assert (digit_count >= 0 );
175
- if (digit_count == 0 ) {
176
- return (PyLongObject * )_PyLong_GetZero ();
177
- }
178
- PyLongObject * result = _PyLong_New (digit_count );
179
- if (result == NULL ) {
180
- PyErr_NoMemory ();
174
+ PyLongWriter * writer = PyLongWriter_Create ();
175
+ if (writer == NULL ) {
181
176
return NULL ;
182
177
}
183
- _PyLong_SetSignAndDigitCount (result , negative ?-1 :1 , digit_count );
184
- memcpy (result -> long_value .ob_digit , digits , digit_count * sizeof (digit ));
185
- return result ;
178
+
179
+ if (negative ) {
180
+ PyLongWriter_SetSign (writer , -1 );
181
+ }
182
+
183
+ Py_digit * writer_digits = PyLongWriter_AllocDigits (writer , digit_count );
184
+ if (writer_digits == NULL ) {
185
+ goto error ;
186
+ }
187
+ memcpy (writer_digits , digits , digit_count * sizeof (digit ));
188
+
189
+ return (PyLongObject * )PyLongWriter_Finish (writer );
190
+
191
+ error :
192
+ PyLongWriter_Discard (writer );
193
+ return NULL ;
186
194
}
187
195
188
196
PyObject *
@@ -6729,3 +6737,70 @@ PyUnstable_Long_ReleaseExport(PyUnstable_Long_DigitArray *array)
6729
6737
array -> ndigits = 0 ;
6730
6738
array -> digits = NULL ;
6731
6739
}
6740
+
6741
+
6742
+ /* --- PyLongWriter API --------------------------------------------------- */
6743
+
6744
+ struct PyLongWriter {
6745
+ PyLongObject * obj ;
6746
+ int sign ;
6747
+ };
6748
+
6749
+ PyLongWriter * PyLongWriter_Create (void )
6750
+ {
6751
+ PyLongWriter * writer = PyMem_Malloc (sizeof (PyLongWriter ));
6752
+ if (writer == NULL ) {
6753
+ PyErr_NoMemory ();
6754
+ return NULL ;
6755
+ }
6756
+ writer -> obj = NULL ;
6757
+ writer -> sign = 1 ;
6758
+ return writer ;
6759
+ }
6760
+
6761
+ Py_digit * PyLongWriter_AllocDigits (PyLongWriter * writer , size_t ndigits )
6762
+ {
6763
+ Py_CLEAR (writer -> obj );
6764
+
6765
+ if (ndigits > (size_t )PY_SSIZE_T_MAX ) {
6766
+ PyErr_NoMemory ();
6767
+ return NULL ;
6768
+ }
6769
+
6770
+ writer -> obj = _PyLong_New (ndigits );
6771
+ if (writer -> obj == NULL ) {
6772
+ return NULL ;
6773
+ }
6774
+
6775
+ return writer -> obj -> long_value .ob_digit ;
6776
+ }
6777
+
6778
+ void PyLongWriter_SetSign (PyLongWriter * writer , int sign )
6779
+ {
6780
+ writer -> sign = sign ;
6781
+ }
6782
+
6783
+ PyObject * PyLongWriter_Finish (PyLongWriter * writer )
6784
+ {
6785
+ if (writer -> obj ) {
6786
+ assert (Py_REFCNT (writer -> obj ) == 1 );
6787
+
6788
+ if (writer -> sign < 0 && _PyLong_IsPositive (writer -> obj )) {
6789
+ _PyLong_FlipSign (writer -> obj );
6790
+ }
6791
+
6792
+ writer -> obj = maybe_small_long (long_normalize (writer -> obj ));
6793
+ }
6794
+ else {
6795
+ writer -> obj = (PyLongObject * )Py_NewRef (_PyLong_GetZero ());
6796
+ }
6797
+
6798
+ PyObject * res = (PyObject * )writer -> obj ;
6799
+ PyMem_Free (writer );
6800
+ return res ;
6801
+ }
6802
+
6803
+ void PyLongWriter_Discard (PyLongWriter * writer )
6804
+ {
6805
+ PyMem_Free (writer );
6806
+ }
0 commit comments