|
10 | 10 | #define PY_SSIZE_T_CLEAN |
11 | 11 | #include "Python.h" |
12 | 12 | #include "pycore_moduleobject.h" // _PyModule_GetState() |
| 13 | +#include "pycore_bytesobject.h" // _PyBytes_Repeat |
13 | 14 | #include "structmember.h" // PyMemberDef |
14 | 15 | #include <stddef.h> // offsetof() |
15 | 16 | #include <stddef.h> |
@@ -910,34 +911,24 @@ static PyObject * |
910 | 911 | array_repeat(arrayobject *a, Py_ssize_t n) |
911 | 912 | { |
912 | 913 | array_state *state = find_array_state_by_type(Py_TYPE(a)); |
913 | | - Py_ssize_t size; |
914 | | - arrayobject *np; |
915 | | - Py_ssize_t oldbytes, newbytes; |
| 914 | + |
916 | 915 | if (n < 0) |
917 | 916 | n = 0; |
918 | | - if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) { |
| 917 | + const Py_ssize_t array_length = Py_SIZE(a); |
| 918 | + if ((array_length != 0) && (n > PY_SSIZE_T_MAX / array_length)) { |
919 | 919 | return PyErr_NoMemory(); |
920 | 920 | } |
921 | | - size = Py_SIZE(a) * n; |
922 | | - np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); |
| 921 | + Py_ssize_t size = array_length * n; |
| 922 | + arrayobject* np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr); |
923 | 923 | if (np == NULL) |
924 | 924 | return NULL; |
925 | 925 | if (size == 0) |
926 | 926 | return (PyObject *)np; |
927 | | - oldbytes = Py_SIZE(a) * a->ob_descr->itemsize; |
928 | | - newbytes = oldbytes * n; |
929 | | - /* this follows the code in unicode_repeat */ |
930 | | - if (oldbytes == 1) { |
931 | | - memset(np->ob_item, a->ob_item[0], newbytes); |
932 | | - } else { |
933 | | - Py_ssize_t done = oldbytes; |
934 | | - memcpy(np->ob_item, a->ob_item, oldbytes); |
935 | | - while (done < newbytes) { |
936 | | - Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done; |
937 | | - memcpy(np->ob_item+done, np->ob_item, ncopy); |
938 | | - done += ncopy; |
939 | | - } |
940 | | - } |
| 927 | + |
| 928 | + const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize; |
| 929 | + const Py_ssize_t newbytes = oldbytes * n; |
| 930 | + _PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes); |
| 931 | + |
941 | 932 | return (PyObject *)np; |
942 | 933 | } |
943 | 934 |
|
@@ -1075,27 +1066,23 @@ array_inplace_concat(arrayobject *self, PyObject *bb) |
1075 | 1066 | static PyObject * |
1076 | 1067 | array_inplace_repeat(arrayobject *self, Py_ssize_t n) |
1077 | 1068 | { |
1078 | | - char *items, *p; |
1079 | | - Py_ssize_t size, i; |
| 1069 | + const Py_ssize_t array_size = Py_SIZE(self); |
1080 | 1070 |
|
1081 | | - if (Py_SIZE(self) > 0) { |
| 1071 | + if (array_size > 0 && n != 1 ) { |
1082 | 1072 | if (n < 0) |
1083 | 1073 | n = 0; |
1084 | 1074 | if ((self->ob_descr->itemsize != 0) && |
1085 | | - (Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { |
| 1075 | + (array_size > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) { |
1086 | 1076 | return PyErr_NoMemory(); |
1087 | 1077 | } |
1088 | | - size = Py_SIZE(self) * self->ob_descr->itemsize; |
| 1078 | + Py_ssize_t size = array_size * self->ob_descr->itemsize; |
1089 | 1079 | if (n > 0 && size > PY_SSIZE_T_MAX / n) { |
1090 | 1080 | return PyErr_NoMemory(); |
1091 | 1081 | } |
1092 | | - if (array_resize(self, n * Py_SIZE(self)) == -1) |
| 1082 | + if (array_resize(self, n * array_size) == -1) |
1093 | 1083 | return NULL; |
1094 | | - items = p = self->ob_item; |
1095 | | - for (i = 1; i < n; i++) { |
1096 | | - p += size; |
1097 | | - memcpy(p, items, size); |
1098 | | - } |
| 1084 | + |
| 1085 | + _PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size); |
1099 | 1086 | } |
1100 | 1087 | Py_INCREF(self); |
1101 | 1088 | return (PyObject *)self; |
|
0 commit comments