codekingpro/portable-devtools
115k
1#ifndef Py_INTERNAL_OBJECT_STACK_H2#define Py_INTERNAL_OBJECT_STACK_H3 4#ifdef __cplusplus5extern "C" {6#endif7 8#ifndef Py_BUILD_CORE9# error "this header requires Py_BUILD_CORE define"10#endif11 12// _PyObjectStack is a stack of Python objects implemented as a linked list of13// fixed size buffers.14 15// Chosen so that _PyObjectStackChunk is a power-of-two size.16#define _Py_OBJECT_STACK_CHUNK_SIZE 25417 18typedef struct _PyObjectStackChunk {19 struct _PyObjectStackChunk *prev;20 Py_ssize_t n;21 PyObject *objs[_Py_OBJECT_STACK_CHUNK_SIZE];22} _PyObjectStackChunk;23 24typedef struct _PyObjectStack {25 _PyObjectStackChunk *head;26} _PyObjectStack;27 28 29extern _PyObjectStackChunk *30_PyObjectStackChunk_New(void);31 32extern void33_PyObjectStackChunk_Free(_PyObjectStackChunk *);34 35// Push an item onto the stack. Return -1 on allocation failure, 0 on success.36static inline int37_PyObjectStack_Push(_PyObjectStack *stack, PyObject *obj)38{39 _PyObjectStackChunk *buf = stack->head;40 if (buf == NULL || buf->n == _Py_OBJECT_STACK_CHUNK_SIZE) {41 buf = _PyObjectStackChunk_New();42 if (buf == NULL) {43 return -1;44 }45 buf->prev = stack->head;46 buf->n = 0;47 stack->head = buf;48 }49 50 assert(buf->n >= 0 && buf->n < _Py_OBJECT_STACK_CHUNK_SIZE);51 buf->objs[buf->n] = obj;52 buf->n++;53 return 0;54}55 56// Pop the top item from the stack. Return NULL if the stack is empty.57static inline PyObject *58_PyObjectStack_Pop(_PyObjectStack *stack)59{60 _PyObjectStackChunk *buf = stack->head;61 if (buf == NULL) {62 return NULL;63 }64 assert(buf->n > 0 && buf->n <= _Py_OBJECT_STACK_CHUNK_SIZE);65 buf->n--;66 PyObject *obj = buf->objs[buf->n];67 if (buf->n == 0) {68 stack->head = buf->prev;69 _PyObjectStackChunk_Free(buf);70 }71 return obj;72}73 74static inline Py_ssize_t75_PyObjectStack_Size(_PyObjectStack *stack)76{77 Py_ssize_t size = 0;78 for (_PyObjectStackChunk *buf = stack->head; buf != NULL; buf = buf->prev) {79 size += buf->n;80 }81 return size;82}83 84// Merge src into dst, leaving src empty85extern void86_PyObjectStack_Merge(_PyObjectStack *dst, _PyObjectStack *src);87 88// Remove all items from the stack89extern void90_PyObjectStack_Clear(_PyObjectStack *stack);91 92#ifdef __cplusplus93}94#endif95#endif // !Py_INTERNAL_OBJECT_STACK_H96 