mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-130080: move _Py_EnsureArrayLargeEnough to a separate header so it can be used outside of the compiler (#130930)
This commit is contained in:
parent
9a63138e09
commit
4242c2b8d0
5 changed files with 108 additions and 52 deletions
39
Include/internal/pycore_c_array.h
Normal file
39
Include/internal/pycore_c_array.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
#ifndef Py_INTERNAL_C_ARRAY_H
|
||||
#define Py_INTERNAL_C_ARRAY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
|
||||
/* Utility for a number of growing arrays */
|
||||
|
||||
typedef struct {
|
||||
void *array; /* pointer to the array */
|
||||
int allocated_entries; /* pointer to the capacity of the array */
|
||||
size_t item_size; /* size of each element */
|
||||
int initial_num_entries; /* initial allocation size */
|
||||
} _Py_c_array_t;
|
||||
|
||||
|
||||
int _Py_CArray_Init(_Py_c_array_t* array, int item_size, int initial_num_entries);
|
||||
void _Py_CArray_Fini(_Py_c_array_t* array);
|
||||
|
||||
/* If idx is out of bounds:
|
||||
* If arr->array is NULL, allocate arr->initial_num_entries slots.
|
||||
* Otherwise, double its size.
|
||||
*
|
||||
* Return 0 if successful and -1 (with exception set) otherwise.
|
||||
*/
|
||||
int _Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !Py_INTERNAL_C_ARRAY_H */
|
|
@ -183,14 +183,6 @@ int _PyCodegen_Expression(struct _PyCompiler *c, expr_ty e);
|
|||
int _PyCodegen_Body(struct _PyCompiler *c, _Py_SourceLocation loc, asdl_stmt_seq *stmts,
|
||||
bool is_interactive);
|
||||
|
||||
/* Utility for a number of growing arrays used in the compiler */
|
||||
int _PyCompile_EnsureArrayLargeEnough(
|
||||
int idx,
|
||||
void **array,
|
||||
int *alloc,
|
||||
int default_alloc,
|
||||
size_t item_size);
|
||||
|
||||
int _PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj);
|
||||
|
||||
PyCodeObject *_PyCompile_OptimizeAndAssemble(struct _PyCompiler *c, int addNone);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "Python.h"
|
||||
#include "opcode.h"
|
||||
#include "pycore_c_array.h" // _Py_CArray_EnsureCapacity
|
||||
#include "pycore_flowgraph.h"
|
||||
#include "pycore_compile.h"
|
||||
#include "pycore_intrinsics.h"
|
||||
|
@ -141,13 +142,16 @@ static int
|
|||
basicblock_next_instr(basicblock *b)
|
||||
{
|
||||
assert(b != NULL);
|
||||
RETURN_IF_ERROR(
|
||||
_PyCompile_EnsureArrayLargeEnough(
|
||||
b->b_iused + 1,
|
||||
(void**)&b->b_instr,
|
||||
&b->b_ialloc,
|
||||
DEFAULT_BLOCK_SIZE,
|
||||
sizeof(cfg_instr)));
|
||||
_Py_c_array_t array = {
|
||||
.array = (void*)b->b_instr,
|
||||
.allocated_entries = b->b_ialloc,
|
||||
.item_size = sizeof(cfg_instr),
|
||||
.initial_num_entries = DEFAULT_BLOCK_SIZE,
|
||||
};
|
||||
|
||||
RETURN_IF_ERROR(_Py_CArray_EnsureCapacity(&array, b->b_iused + 1));
|
||||
b->b_instr = array.array;
|
||||
b->b_ialloc = array.allocated_entries;
|
||||
return b->b_iused++;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
#include "Python.h"
|
||||
|
||||
#include "pycore_compile.h" // _PyCompile_EnsureArrayLargeEnough
|
||||
#include "pycore_c_array.h" // _Py_CArray_EnsureCapacity
|
||||
#include "pycore_compile.h" // _PyInstruction
|
||||
#include "pycore_opcode_utils.h"
|
||||
#include "pycore_opcode_metadata.h" // OPCODE_HAS_ARG, etc
|
||||
|
||||
|
@ -36,12 +37,18 @@ static int
|
|||
instr_sequence_next_inst(instr_sequence *seq) {
|
||||
assert(seq->s_instrs != NULL || seq->s_used == 0);
|
||||
|
||||
RETURN_IF_ERROR(
|
||||
_PyCompile_EnsureArrayLargeEnough(seq->s_used + 1,
|
||||
(void**)&seq->s_instrs,
|
||||
&seq->s_allocated,
|
||||
INITIAL_INSTR_SEQUENCE_SIZE,
|
||||
sizeof(instruction)));
|
||||
|
||||
_Py_c_array_t array = {
|
||||
.array = (void*)seq->s_instrs,
|
||||
.allocated_entries = seq->s_allocated,
|
||||
.item_size = sizeof(instruction),
|
||||
.initial_num_entries = INITIAL_INSTR_SEQUENCE_SIZE,
|
||||
};
|
||||
|
||||
RETURN_IF_ERROR(_Py_CArray_EnsureCapacity(&array, seq->s_used + 1));
|
||||
seq->s_instrs = array.array;
|
||||
seq->s_allocated = array.allocated_entries;
|
||||
|
||||
assert(seq->s_allocated >= 0);
|
||||
assert(seq->s_used < seq->s_allocated);
|
||||
return seq->s_used++;
|
||||
|
@ -58,12 +65,16 @@ int
|
|||
_PyInstructionSequence_UseLabel(instr_sequence *seq, int lbl)
|
||||
{
|
||||
int old_size = seq->s_labelmap_size;
|
||||
RETURN_IF_ERROR(
|
||||
_PyCompile_EnsureArrayLargeEnough(lbl,
|
||||
(void**)&seq->s_labelmap,
|
||||
&seq->s_labelmap_size,
|
||||
INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE,
|
||||
sizeof(int)));
|
||||
_Py_c_array_t array = {
|
||||
.array = (void*)seq->s_labelmap,
|
||||
.allocated_entries = seq->s_labelmap_size,
|
||||
.item_size = sizeof(int),
|
||||
.initial_num_entries = INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE,
|
||||
};
|
||||
|
||||
RETURN_IF_ERROR(_Py_CArray_EnsureCapacity(&array, lbl));
|
||||
seq->s_labelmap = array.array;
|
||||
seq->s_labelmap_size = array.allocated_entries;
|
||||
|
||||
for(int i = old_size; i < seq->s_labelmap_size; i++) {
|
||||
seq->s_labelmap[i] = -111; /* something weird, for debugging */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue