@@ -1634,6 +1634,52 @@ encoder_encode_key_value(PyEncoderObject *s, PyUnicodeWriter *writer, bool *firs
16341634 return 0 ;
16351635}
16361636
1637+ static inline int
1638+ _encoder_iterate_mapping_lock_held (PyEncoderObject * s , PyUnicodeWriter * writer ,
1639+ PyObject * dct , PyObject * items ,
1640+ Py_ssize_t indent_level , PyObject * indent_cache ,
1641+ PyObject * separator )
1642+ {
1643+ PyObject * key , * value ;
1644+ bool first = true;
1645+ for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (items ); i ++ ) {
1646+ PyObject * item = PyList_GET_ITEM (items , i );
1647+
1648+ if (!PyTuple_Check (item ) || PyTuple_GET_SIZE (item ) != 2 ) {
1649+ PyErr_SetString (PyExc_ValueError , "items must return 2-tuples" );
1650+ return -1 ;
1651+ }
1652+
1653+ key = PyTuple_GET_ITEM (item , 0 );
1654+ value = PyTuple_GET_ITEM (item , 1 );
1655+ if (encoder_encode_key_value (s , writer , & first , dct , key , value ,
1656+ indent_level , indent_cache ,
1657+ separator ) < 0 ) {
1658+ return -1 ;
1659+ }
1660+ }
1661+
1662+ return 0 ;
1663+ }
1664+
1665+ static inline int
1666+ _encoder_iterate_dict_lock_held (PyEncoderObject * s , PyUnicodeWriter * writer ,
1667+ PyObject * dct , Py_ssize_t indent_level ,
1668+ PyObject * indent_cache , PyObject * separator )
1669+ {
1670+ PyObject * key , * value ;
1671+ Py_ssize_t pos = 0 ;
1672+ bool first = true;
1673+ while (PyDict_Next (dct , & pos , & key , & value )) {
1674+ if (encoder_encode_key_value (s , writer , & first , dct , key , value ,
1675+ indent_level , indent_cache ,
1676+ separator ) < 0 ) {
1677+ return -1 ;
1678+ }
1679+ }
1680+ return 0 ;
1681+ }
1682+
16371683static int
16381684encoder_listencode_dict (PyEncoderObject * s , PyUnicodeWriter * writer ,
16391685 PyObject * dct ,
@@ -1642,8 +1688,6 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer,
16421688 /* Encode Python dict dct a JSON term */
16431689 PyObject * ident = NULL ;
16441690 PyObject * items = NULL ;
1645- PyObject * key , * value ;
1646- bool first = true;
16471691
16481692 if (PyDict_GET_SIZE (dct ) == 0 ) {
16491693 /* Fast path */
@@ -1683,46 +1727,30 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer,
16831727
16841728 if (s -> sort_keys || !PyDict_CheckExact (dct )) {
16851729 items = PyMapping_Items (dct );
1686- if (items == NULL || (s -> sort_keys && PyList_Sort (items ) < 0 ))
1730+ if (items == NULL || (s -> sort_keys && PyList_Sort (items ) < 0 )) {
16871731 goto bail ;
1732+ }
16881733
1734+ int result ;
16891735 Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST (items );
1690- for (Py_ssize_t i = 0 ; i < PyList_GET_SIZE (items ); i ++ ) {
1691- PyObject * item = PyList_GET_ITEM (items , i );
1692-
1693- if (!PyTuple_Check (item ) || PyTuple_GET_SIZE (item ) != 2 ) {
1694- PyErr_SetString (PyExc_ValueError , "items must return 2-tuples" );
1695- Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST ();
1696- goto bail ;
1697- }
1698-
1699- key = PyTuple_GET_ITEM (item , 0 );
1700- value = PyTuple_GET_ITEM (item , 1 );
1701- if (encoder_encode_key_value (s , writer , & first , dct , key , value ,
1702- new_newline_indent ,
1703- current_item_separator ) < 0 ) {
1704- indent_level , indent_cache ,
1705- separator ) < 0 )
1706- //Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST();
1707- goto bail ;
1708- }
1709- }
1736+ result = _encoder_iterate_mapping_lock_held (s , writer , dct ,
1737+ items , indent_level , indent_cache , separator );
17101738 Py_END_CRITICAL_SECTION_SEQUENCE_FAST ();
17111739 Py_CLEAR (items );
1740+ if (result < 0 ) {
1741+ Py_XDECREF (items );
1742+ goto bail ;
1743+ }
17121744
17131745 } else {
1714- Py_ssize_t pos = 0 ;
1746+ int result ;
17151747 Py_BEGIN_CRITICAL_SECTION (dct );
1716- while (PyDict_Next (dct , & pos , & key , & value )) {
1717- if (encoder_encode_key_value (s , writer , & first , dct , key , value ,
1718- indent_level , indent_cache ,
1719- separator ) < 0 )
1720- //Py_EXIT_CRITICAL_SECTION();
1721-
1722- goto bail ;
1723- }
1724- }
1748+ result = _encoder_iterate_dict_lock_held (s , writer , dct ,
1749+ indent_level , indent_cache , separator );
17251750 Py_END_CRITICAL_SECTION ();
1751+ if (result < 0 ) {
1752+ goto bail ;
1753+ }
17261754 }
17271755
17281756 if (ident != NULL ) {
@@ -1748,25 +1776,40 @@ encoder_listencode_dict(PyEncoderObject *s, PyUnicodeWriter *writer,
17481776 return -1 ;
17491777}
17501778
1779+ static inline int
1780+ _encoder_iterate_fast_seq_lock_held (PyEncoderObject * s , PyUnicodeWriter * writer ,
1781+ PyObject * seq , PyObject * s_fast ,
1782+ Py_ssize_t indent_level , PyObject * indent_cache , PyObject * separator )
1783+ {
1784+ for (Py_ssize_t i = 0 ; i < PySequence_Fast_GET_SIZE (s_fast ); i ++ ) {
1785+ PyObject * obj = PySequence_Fast_GET_ITEM (s_fast , i );
1786+ if (i ) {
1787+ if (PyUnicodeWriter_WriteStr (writer , separator ) < 0 ) {
1788+ return -1 ;
1789+ }
1790+ }
1791+ if (encoder_listencode_obj (s , writer , obj , indent_level , indent_cache )) {
1792+ _PyErr_FormatNote ("when serializing %T item %zd" , seq , i );
1793+ return -1 ;
1794+ }
1795+ }
1796+ return 0 ;
1797+ }
1798+
17511799static int
17521800encoder_listencode_list (PyEncoderObject * s , PyUnicodeWriter * writer ,
17531801 PyObject * seq ,
17541802 Py_ssize_t indent_level , PyObject * indent_cache )
17551803{
17561804 PyObject * ident = NULL ;
17571805 PyObject * s_fast = NULL ;
1758- Py_ssize_t i ;
17591806
1760- ident = NULL ;
1761- s_fast = PySequence_Fast (seq , "_iterencode_list needs a sequence" );
1807+ s_fast = PySequence_Fast (seq , "encoder_listencode_list needs a sequence" );
17621808 if (s_fast == NULL )
17631809 return -1 ;
17641810
1765- Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST (seq );
1766-
17671811 if (PySequence_Fast_GET_SIZE (s_fast ) == 0 ) {
17681812 Py_DECREF (s_fast );
1769- Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST ();
17701813 return PyUnicodeWriter_WriteUTF8 (writer , "[]" , 2 );
17711814 }
17721815
@@ -1800,16 +1843,13 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer,
18001843 goto bail ;
18011844 }
18021845 }
1803- for (i = 0 ; i < PySequence_Fast_GET_SIZE (s_fast ); i ++ ) {
1804- PyObject * obj = PySequence_Fast_GET_ITEM (s_fast , i );
1805- if (i ) {
1806- if (PyUnicodeWriter_WriteStr (writer , separator ) < 0 )
1807- goto bail ;
1808- }
1809- if (encoder_listencode_obj (s , writer , obj , indent_level , indent_cache )) {
1810- _PyErr_FormatNote ("when serializing %T item %zd" , seq , i );
1811- goto bail ;
1812- }
1846+ int result ;
1847+ Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST (seq );
1848+ result = _encoder_iterate_fast_seq_lock_held (s , writer , seq , s_fast ,
1849+ indent_level , indent_cache , separator );
1850+ Py_END_CRITICAL_SECTION_SEQUENCE_FAST ();
1851+ if (result < -1 ) {
1852+ goto bail ;
18131853 }
18141854 if (ident != NULL ) {
18151855 if (PyDict_DelItem (s -> markers , ident ))
@@ -1828,12 +1868,10 @@ encoder_listencode_list(PyEncoderObject *s, PyUnicodeWriter *writer,
18281868 goto bail ;
18291869 }
18301870 Py_DECREF (s_fast );
1831- Py_EXIT_CRITICAL_SECTION_SEQUENCE_FAST ();
18321871 return 0 ;
18331872
18341873bail :
18351874 Py_XDECREF (ident );
1836- Py_END_CRITICAL_SECTION_SEQUENCE_FAST ();
18371875 Py_DECREF (s_fast );
18381876 return -1 ;
18391877}
0 commit comments