gh-130080: move _Py_EnsureArrayLargeEnough to a separate header so it can be used outside of the compiler (#130930)

This commit is contained in:
Irit Katriel 2025-03-13 16:02:58 +00:00 committed by GitHub
parent 9a63138e09
commit 4242c2b8d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 108 additions and 52 deletions

View file

@ -18,6 +18,7 @@
#define NEED_OPCODE_TABLES
#include "pycore_opcode_utils.h"
#undef NEED_OPCODE_TABLES
#include "pycore_c_array.h" // _Py_c_array_t
#include "pycore_compile.h"
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_NewLabel()
#include "pycore_intrinsics.h"
@ -100,40 +101,48 @@ static const int compare_masks[] = {
[Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS,
};
/*
* Resize the array if index is out of range.
*
* idx: the index we want to access
* arr: pointer to the array
* alloc: pointer to the capacity of the array
* default_alloc: initial number of items
* item_size: size of each item
*
*/
int
_PyCompile_EnsureArrayLargeEnough(int idx, void **array, int *alloc,
int default_alloc, size_t item_size)
_Py_CArray_Init(_Py_c_array_t* array, int item_size, int initial_num_entries) {
memset(array, 0, sizeof(_Py_c_array_t));
array->item_size = item_size;
array->initial_num_entries = initial_num_entries;
return 0;
}
void
_Py_CArray_Fini(_Py_c_array_t* array)
{
void *arr = *array;
if (array->array) {
PyMem_Free(array->array);
array->allocated_entries = 0;
}
}
int
_Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx)
{
void *arr = c_array->array;
int alloc = c_array->allocated_entries;
if (arr == NULL) {
int new_alloc = default_alloc;
int new_alloc = c_array->initial_num_entries;
if (idx >= new_alloc) {
new_alloc = idx + default_alloc;
new_alloc = idx + c_array->initial_num_entries;
}
arr = PyMem_Calloc(new_alloc, item_size);
arr = PyMem_Calloc(new_alloc, c_array->item_size);
if (arr == NULL) {
PyErr_NoMemory();
return ERROR;
}
*alloc = new_alloc;
alloc = new_alloc;
}
else if (idx >= *alloc) {
size_t oldsize = *alloc * item_size;
int new_alloc = *alloc << 1;
else if (idx >= alloc) {
size_t oldsize = alloc * c_array->item_size;
int new_alloc = alloc << 1;
if (idx >= new_alloc) {
new_alloc = idx + default_alloc;
new_alloc = idx + c_array->initial_num_entries;
}
size_t newsize = new_alloc * item_size;
size_t newsize = new_alloc * c_array->item_size;
if (oldsize > (SIZE_MAX >> 1)) {
PyErr_NoMemory();
@ -146,12 +155,13 @@ _PyCompile_EnsureArrayLargeEnough(int idx, void **array, int *alloc,
PyErr_NoMemory();
return ERROR;
}
*alloc = new_alloc;
alloc = new_alloc;
arr = tmp;
memset((char *)arr + oldsize, 0, newsize - oldsize);
}
*array = arr;
c_array->array = arr;
c_array->allocated_entries = alloc;
return SUCCESS;
}