diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index 177e6d10134adb..27a7a46152f57b 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -62,9 +62,11 @@ _PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, // // Export for 'array' shared extension. PyAPI_FUNC(void) -_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, +_PyBytes_RepeatBuffer(char* dest, Py_ssize_t len_dest, const char* src, Py_ssize_t len_src); +PyAPI_FUNC(PyObject *) _PyBytes_Repeat(PyObject *self, Py_ssize_t n); + /* _PyBytesObject_SIZE gives the basic size of a bytes object; any memory allocation for a bytes object of length n should request PyBytesObject_SIZE + n bytes. diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index bf80f96396ea4a..e294b16b3df60f 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -29,6 +29,7 @@ PyAPI_FUNC(PyObject *)_PyTuple_FromStackRefStealOnSuccess(const union _PyStackRe PyAPI_FUNC(PyObject *)_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t); PyAPI_FUNC(PyObject *) _PyTuple_BinarySlice(PyObject *, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyTuple_Concat(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyTuple_Repeat(PyObject *self, Py_ssize_t n); PyAPI_FUNC(PyObject *) _PyTuple_FromPair(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyTuple_FromPairSteal(PyObject *, PyObject *); diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 74d84052a2bb2b..75d5068f815b91 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -33,6 +33,7 @@ extern PyObject* _PyUnicode_ResizeCompact( Py_ssize_t length); extern PyObject* _PyUnicode_GetEmpty(void); PyAPI_FUNC(PyObject*) _PyUnicode_BinarySlice(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyUnicode_Repeat(PyObject *str, Py_ssize_t len); /* Generic helper macro to convert characters of different types. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index b01e92eb8873ba..6322bc3d0bd22a 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -8,7 +8,7 @@ #endif #include "Python.h" -#include "pycore_bytesobject.h" // _PyBytes_Repeat +#include "pycore_bytesobject.h" // _PyBytes_RepeatBuffer #include "pycore_call.h" // _PyObject_CallMethod() #include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_floatobject.h" // _PY_FLOAT_BIG_ENDIAN @@ -1148,7 +1148,7 @@ array_repeat(PyObject *op, Py_ssize_t n) const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize; const Py_ssize_t newbytes = oldbytes * n; - _PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes); + _PyBytes_RepeatBuffer(np->ob_item, newbytes, a->ob_item, oldbytes); return (PyObject *)np; } @@ -1305,7 +1305,7 @@ array_inplace_repeat(PyObject *op, Py_ssize_t n) if (array_resize(self, n * array_size) == -1) return NULL; - _PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size); + _PyBytes_RepeatBuffer(self->ob_item, n*size, self->ob_item, size); } return Py_NewRef(self); } diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c583193b5a252c..e698d260795480 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -402,7 +402,7 @@ bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count) PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size); const char* buf = PyByteArray_AS_STRING(self); if (result != NULL && size != 0) { - _PyBytes_Repeat(result->ob_bytes, size, buf, mysize); + _PyBytes_RepeatBuffer(result->ob_bytes, size, buf, mysize); } return (PyObject *)result; } @@ -439,7 +439,7 @@ bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count) } char* buf = PyByteArray_AS_STRING(self); - _PyBytes_Repeat(buf, size, buf, mysize); + _PyBytes_RepeatBuffer(buf, size, buf, mysize); return Py_NewRef(self); } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8a9d1b133affb3..cd8417e2583916 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3,7 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_bytes_methods.h" // _Py_bytes_startswith() -#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat() +#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_RepeatBuffer() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_format.h" // F_LJUST @@ -1581,8 +1581,8 @@ _PyBytes_Concat(PyObject *a, PyObject *b) return result; } -static PyObject * -bytes_repeat(PyObject *self, Py_ssize_t n) +PyObject * +_PyBytes_Repeat(PyObject *self, Py_ssize_t n) { PyBytesObject *a = _PyBytes_CAST(self); if (n < 0) @@ -1613,7 +1613,7 @@ bytes_repeat(PyObject *self, Py_ssize_t n) set_ob_shash(op, -1); op->ob_sval[size] = '\0'; - _PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a)); + _PyBytes_RepeatBuffer(op->ob_sval, size, a->ob_sval, Py_SIZE(a)); return (PyObject *) op; } @@ -1805,7 +1805,7 @@ bytes_buffer_getbuffer(PyObject *op, Py_buffer *view, int flags) static PySequenceMethods bytes_as_sequence = { bytes_length, /*sq_length*/ _PyBytes_Concat, /*sq_concat*/ - bytes_repeat, /*sq_repeat*/ + _PyBytes_Repeat, /*sq_repeat*/ bytes_item, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ @@ -3555,7 +3555,7 @@ bytes_iter(PyObject *seq) void -_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, +_PyBytes_RepeatBuffer(char* dest, Py_ssize_t len_dest, const char* src, Py_ssize_t len_src) { if (len_dest == 0) { diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 7757a102677e2c..ed66bab16198c0 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -594,8 +594,8 @@ _PyTuple_Concat(PyObject *aa, PyObject *bb) return (PyObject *)np; } -static PyObject * -tuple_repeat(PyObject *self, Py_ssize_t n) +PyObject * +_PyTuple_Repeat(PyObject *self, Py_ssize_t n) { PyTupleObject *a = _PyTuple_CAST(self); const Py_ssize_t input_size = Py_SIZE(a); @@ -865,7 +865,7 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable) static PySequenceMethods tuple_as_sequence = { tuple_length, /* sq_length */ _PyTuple_Concat, /* sq_concat */ - tuple_repeat, /* sq_repeat */ + _PyTuple_Repeat, /* sq_repeat */ tuple_item, /* sq_item */ 0, /* sq_slice */ 0, /* sq_ass_item */ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d2569132998acc..c604a9157c39ee 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -41,7 +41,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_bytes_methods.h" // _Py_bytes_lower() -#include "pycore_bytesobject.h" // _PyBytes_Repeat() +#include "pycore_bytesobject.h" // _PyBytes_RepeatBuffer() #include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_codecs.h" // _PyCodec_Lookup() #include "pycore_critical_section.h" // Py_*_CRITICAL_SECTION_SEQUENCE_FAST @@ -12494,8 +12494,8 @@ unicode_rstrip_impl(PyObject *self, PyObject *chars) } -static PyObject* -unicode_repeat(PyObject *str, Py_ssize_t len) +PyObject * +_PyUnicode_Repeat(PyObject *str, Py_ssize_t len) { PyObject *u; Py_ssize_t nchars, n; @@ -12540,7 +12540,7 @@ unicode_repeat(PyObject *str, Py_ssize_t len) else { Py_ssize_t char_size = PyUnicode_KIND(str); char *to = (char *) PyUnicode_DATA(u); - _PyBytes_Repeat(to, nchars * char_size, PyUnicode_DATA(str), + _PyBytes_RepeatBuffer(to, nchars * char_size, PyUnicode_DATA(str), PyUnicode_GET_LENGTH(str) * char_size); } @@ -13726,7 +13726,7 @@ static PyNumberMethods unicode_as_number = { static PySequenceMethods unicode_as_sequence = { unicode_length, /* sq_length */ PyUnicode_Concat, /* sq_concat */ - unicode_repeat, /* sq_repeat */ + _PyUnicode_Repeat, /* sq_repeat */ unicode_getitem, /* sq_item */ 0, /* sq_slice */ 0, /* sq_ass_item */ diff --git a/Python/specialize.c b/Python/specialize.c index 793bac58adf41a..cb4dbca1b493be 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -2122,54 +2122,64 @@ is_compactlong(PyObject *v) _PyLong_IsCompact((PyLongObject *)v); } -/* sequence * int helpers: bypass PyNumber_Multiply dispatch overhead - by calling sq_repeat directly with PyLong_AsSsize_t. */ - -static inline PyObject * -seq_int_multiply(PyObject *seq, PyObject *n, - ssizeargfunc repeat) +static PyObject * +str_int_multiply(PyObject *lhs, PyObject *rhs) { - Py_ssize_t count = PyLong_AsSsize_t(n); + Py_ssize_t count = PyLong_AsSsize_t(rhs); if (count == -1 && PyErr_Occurred()) { return NULL; } - return repeat(seq, count); -} - -static PyObject * -str_int_multiply(PyObject *lhs, PyObject *rhs) -{ - return seq_int_multiply(lhs, rhs, PyUnicode_Type.tp_as_sequence->sq_repeat); + return _PyUnicode_Repeat(lhs, count); } static PyObject * int_str_multiply(PyObject *lhs, PyObject *rhs) { - return seq_int_multiply(rhs, lhs, PyUnicode_Type.tp_as_sequence->sq_repeat); + Py_ssize_t count = PyLong_AsSsize_t(lhs); + if (count == -1 && PyErr_Occurred()) { + return NULL; + } + return _PyUnicode_Repeat(rhs, count); } static PyObject * bytes_int_multiply(PyObject *lhs, PyObject *rhs) { - return seq_int_multiply(lhs, rhs, PyBytes_Type.tp_as_sequence->sq_repeat); + Py_ssize_t count = PyLong_AsSsize_t(rhs); + if (count == -1 && PyErr_Occurred()) { + return NULL; + } + return _PyBytes_Repeat(lhs, count); } static PyObject * int_bytes_multiply(PyObject *lhs, PyObject *rhs) { - return seq_int_multiply(rhs, lhs, PyBytes_Type.tp_as_sequence->sq_repeat); + Py_ssize_t count = PyLong_AsSsize_t(lhs); + if (count == -1 && PyErr_Occurred()) { + return NULL; + } + return _PyBytes_Repeat(rhs, count); } static PyObject * tuple_int_multiply(PyObject *lhs, PyObject *rhs) { - return seq_int_multiply(lhs, rhs, PyTuple_Type.tp_as_sequence->sq_repeat); + Py_ssize_t count = PyLong_AsSsize_t(rhs); + if (count == -1 && PyErr_Occurred()) { + return NULL; + } + return _PyTuple_Repeat(lhs, count); } static PyObject * int_tuple_multiply(PyObject *lhs, PyObject *rhs) { - return seq_int_multiply(rhs, lhs, PyTuple_Type.tp_as_sequence->sq_repeat); + Py_ssize_t count = PyLong_AsSsize_t(lhs); + if (count == -1 && PyErr_Occurred()) { + return NULL; + } + return _PyTuple_Repeat(rhs, count); } static int @@ -2290,8 +2300,8 @@ static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = { to be a freshly allocated object. */ {NB_ADD, NULL, _PyTuple_Concat, &PyTuple_Type, 0, &PyTuple_Type, &PyTuple_Type}, - /* str * int / int * str: call unicode_repeat directly. - unicode_repeat returns the original when n == 1. */ + /* str * int / int * str: call _PyUnicode_Repeat directly. + _PyUnicode_Repeat returns the original when n == 1. */ {NB_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type}, {NB_MULTIPLY, NULL, int_str_multiply, &PyUnicode_Type, 0, &PyLong_Type, &PyUnicode_Type}, {NB_INPLACE_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type}, @@ -2302,15 +2312,15 @@ static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = { {NB_ADD, NULL, _PyBytes_Concat, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type}, {NB_INPLACE_ADD, NULL, _PyBytes_Concat, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type}, - /* bytes * int / int * bytes: call bytes_repeat directly. - bytes_repeat returns the original when n == 1. */ + /* bytes * int / int * bytes: call _PyBytes_Repeat directly. + _PyBytes_Repeat returns the original when n == 1. */ {NB_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type}, {NB_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type}, {NB_INPLACE_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type}, {NB_INPLACE_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type}, - /* tuple * int / int * tuple: call tuple_repeat directly. - tuple_repeat returns the original when n == 1. */ + /* tuple * int / int * tuple: call _PyTuple_Repeat directly. + _PyTuple_Repeat returns the original when n == 1. */ {NB_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type}, {NB_MULTIPLY, NULL, int_tuple_multiply, &PyTuple_Type, 0, &PyLong_Type, &PyTuple_Type}, {NB_INPLACE_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},