File indexing completed on 2025-11-19 09:50:48
0001 #ifndef Py_INTERNAL_OBJECT_STACK_H
0002 #define Py_INTERNAL_OBJECT_STACK_H
0003
0004 #include "pycore_freelist.h" // _PyFreeListState
0005
0006 #ifdef __cplusplus
0007 extern "C" {
0008 #endif
0009
0010 #ifndef Py_BUILD_CORE
0011 # error "this header requires Py_BUILD_CORE define"
0012 #endif
0013
0014
0015
0016
0017
0018 #define _Py_OBJECT_STACK_CHUNK_SIZE 254
0019
0020 typedef struct _PyObjectStackChunk {
0021 struct _PyObjectStackChunk *prev;
0022 Py_ssize_t n;
0023 PyObject *objs[_Py_OBJECT_STACK_CHUNK_SIZE];
0024 } _PyObjectStackChunk;
0025
0026 typedef struct _PyObjectStack {
0027 _PyObjectStackChunk *head;
0028 } _PyObjectStack;
0029
0030
0031 extern _PyObjectStackChunk *
0032 _PyObjectStackChunk_New(void);
0033
0034 extern void
0035 _PyObjectStackChunk_Free(_PyObjectStackChunk *);
0036
0037
0038 static inline int
0039 _PyObjectStack_Push(_PyObjectStack *stack, PyObject *obj)
0040 {
0041 _PyObjectStackChunk *buf = stack->head;
0042 if (buf == NULL || buf->n == _Py_OBJECT_STACK_CHUNK_SIZE) {
0043 buf = _PyObjectStackChunk_New();
0044 if (buf == NULL) {
0045 return -1;
0046 }
0047 buf->prev = stack->head;
0048 buf->n = 0;
0049 stack->head = buf;
0050 }
0051
0052 assert(buf->n >= 0 && buf->n < _Py_OBJECT_STACK_CHUNK_SIZE);
0053 buf->objs[buf->n] = obj;
0054 buf->n++;
0055 return 0;
0056 }
0057
0058
0059 static inline PyObject *
0060 _PyObjectStack_Pop(_PyObjectStack *stack)
0061 {
0062 _PyObjectStackChunk *buf = stack->head;
0063 if (buf == NULL) {
0064 return NULL;
0065 }
0066 assert(buf->n > 0 && buf->n <= _Py_OBJECT_STACK_CHUNK_SIZE);
0067 buf->n--;
0068 PyObject *obj = buf->objs[buf->n];
0069 if (buf->n == 0) {
0070 stack->head = buf->prev;
0071 _PyObjectStackChunk_Free(buf);
0072 }
0073 return obj;
0074 }
0075
0076 static inline Py_ssize_t
0077 _PyObjectStack_Size(_PyObjectStack *stack)
0078 {
0079 Py_ssize_t size = 0;
0080 for (_PyObjectStackChunk *buf = stack->head; buf != NULL; buf = buf->prev) {
0081 size += buf->n;
0082 }
0083 return size;
0084 }
0085
0086
0087 extern void
0088 _PyObjectStack_Merge(_PyObjectStack *dst, _PyObjectStack *src);
0089
0090
0091 extern void
0092 _PyObjectStack_Clear(_PyObjectStack *stack);
0093
0094 #ifdef __cplusplus
0095 }
0096 #endif
0097 #endif