Addressed PR comments.

pull/13171/head
Joshua Haberman 3 years ago
parent 2d4ffbf1c4
commit d067bd3f41
  1. 38
      python/repeated.c
  2. 14
      upb/reflection.c
  3. 6
      upb/reflection.h

@ -243,7 +243,7 @@ PyObject* PyUpb_RepeatedContainer_ToList(PyObject* _self) {
PyObject* list = PyList_New(n); PyObject* list = PyList_New(n);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
PyObject* val = PyUpb_UpbToPy(upb_array_get(arr, i), f, self->arena); PyObject* val = PyUpb_UpbToPy(upb_array_get(arr, i), f, self->arena);
PyList_SetItem(list, n, val); PyList_SetItem(list, i, val);
} }
return list; return list;
} }
@ -315,7 +315,9 @@ static int PyUpb_RepeatedContainer_SetSubscript(
// Set range. // Set range.
PyObject* seq = PyObject* seq =
PySequence_Fast(value, "must assign iterable to extended slice"); PySequence_Fast(value, "must assign iterable to extended slice");
PyObject* item = NULL;
if (!seq) return -1; if (!seq) return -1;
int ret = -1;
if (PySequence_Size(seq) != count) { if (PySequence_Size(seq) != count) {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"attempt to assign sequence of size %zd to extended slice " "attempt to assign sequence of size %zd to extended slice "
@ -326,35 +328,37 @@ static int PyUpb_RepeatedContainer_SetSubscript(
} }
for (Py_ssize_t i = 0; i < count; i++, idx += step) { for (Py_ssize_t i = 0; i < count; i++, idx += step) {
upb_msgval msgval; upb_msgval msgval;
PyObject* item = PySequence_GetItem(seq, i); item = PySequence_GetItem(seq, i);
if (!item) goto err;
// XXX: if this fails we can leave the list partially mutated. // XXX: if this fails we can leave the list partially mutated.
bool ok = PyUpb_PyToUpb(item, f, &msgval, arena); if (!PyUpb_PyToUpb(item, f, &msgval, arena)) goto err;
Py_DECREF(item);
if (!ok) return -1;
upb_array_set(arr, idx, msgval); upb_array_set(arr, idx, msgval);
} }
return 0; ret = 0;
err:
Py_XDECREF(seq);
Py_XDECREF(item);
return ret;
} }
static int PyUpb_RepeatedContainer_DeleteSubscript(upb_array* arr, static int PyUpb_RepeatedContainer_DeleteSubscript(upb_array* arr,
Py_ssize_t idx, Py_ssize_t idx,
Py_ssize_t count, Py_ssize_t count,
Py_ssize_t step) { Py_ssize_t step) {
// This is a delete, not a set.
// Normalize direction: deletion is order-independent. // Normalize direction: deletion is order-independent.
if (step > 0) { Py_ssize_t start = idx;
idx += step * (count - 1); if (step < 0) {
Py_ssize_t end = start + step * (count - 1);
start = end;
step = -step; step = -step;
} }
if (step == -1) { size_t dst = start;
// Contiguous range. size_t src = start + 1;
upb_array_delete(arr, idx - (count - 1), count); for (Py_ssize_t i = 0; i < count; i++, dst += step, src += step + 1) {
} else { upb_array_move(arr, dst, src, step);
// Stepped slice.
for (Py_ssize_t i = 0; i < count; i++, idx += step) {
upb_array_delete(arr, idx, 1);
}
} }
upb_array_resize(arr, upb_array_size(arr) - count, NULL);
return 0; return 0;
} }

@ -373,6 +373,12 @@ bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) {
return true; return true;
} }
bool upb_array_move(upb_array* arr, size_t dst_idx, size_t src_idx,
size_t count) {
char* data = _upb_array_ptr(arr);
int lg2 = arr->data & 7;
memmove(&data[dst_idx << lg2], &data[src_idx << lg2], count << lg2);
}
bool upb_array_insert(upb_array *arr, size_t i, size_t count, bool upb_array_insert(upb_array *arr, size_t i, size_t count,
upb_arena *arena) { upb_arena *arena) {
@ -382,9 +388,7 @@ bool upb_array_insert(upb_array *arr, size_t i, size_t count,
if (!upb_array_resize(arr, arr->len + count, arena)) { if (!upb_array_resize(arr, arr->len + count, arena)) {
return false; return false;
} }
char* data = _upb_array_ptr(arr); upb_array_move(arr, i + count, i, oldsize - i);
int lg2 = arr->data & 7;
memmove(&data[(i + count) << lg2], &data[i << lg2], (oldsize - i) << lg2);
return true; return true;
} }
@ -396,9 +400,7 @@ void upb_array_delete(upb_array *arr, size_t i, size_t count) {
size_t end = i + count; size_t end = i + count;
UPB_ASSERT(end >= i); UPB_ASSERT(end >= i);
UPB_ASSERT(end <= arr->len); UPB_ASSERT(end <= arr->len);
char* data = _upb_array_ptr(arr); upb_array_move(arr, i, end, arr->len - end);
int lg2 = arr->data & 7;
memmove(&data[i << lg2], &data[end << lg2], (arr->len - end) << lg2);
arr->len -= count; arr->len -= count;
} }

@ -134,11 +134,15 @@ void upb_array_set(upb_array *arr, size_t i, upb_msgval val);
/* Appends an element to the array. Returns false on allocation failure. */ /* Appends an element to the array. Returns false on allocation failure. */
bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena); bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena);
/* Moves elements within the array using memmove(). Like memmove(), the source
* and destination elements may be overlapping. */
bool upb_array_move(upb_array* array, size_t dst_idx, size_t src_idx,
size_t count);
/* Inserts one or more empty elements into the array. Existing elements are /* Inserts one or more empty elements into the array. Existing elements are
* shifted right. The new elements have undefined state and must be set with * shifted right. The new elements have undefined state and must be set with
* `upb_array_set()`. * `upb_array_set()`.
* REQUIRES: i <= `upb_array_size(arr)` */ * REQUIRES: `i <= upb_array_size(arr)` */
bool upb_array_insert(upb_array *array, size_t i, size_t count, bool upb_array_insert(upb_array *array, size_t i, size_t count,
upb_arena *arena); upb_arena *arena);

Loading…
Cancel
Save