--- /dev/null
+#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 */
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);
#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"
[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
+_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)
+{
+ if (array->array) {
+ PyMem_Free(array->array);
+ array->allocated_entries = 0;
+ }
+}
+
int
-_PyCompile_EnsureArrayLargeEnough(int idx, void **array, int *alloc,
- int default_alloc, size_t item_size)
+_Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx)
{
- void *arr = *array;
+ 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();
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;
}
#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"
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++;
}
#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
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++;
_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 */