diff options
Diffstat (limited to 'Zend/zend_stack.c')
-rw-r--r-- | Zend/zend_stack.c | 82 |
1 files changed, 43 insertions, 39 deletions
diff --git a/Zend/zend_stack.c b/Zend/zend_stack.c index 3e7401f5ff..03b23427cb 100644 --- a/Zend/zend_stack.c +++ b/Zend/zend_stack.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | @@ -22,80 +22,66 @@ #include "zend.h" #include "zend_stack.h" -ZEND_API int zend_stack_init(zend_stack *stack) +#define ZEND_STACK_ELEMENT(stack, n) ((void *)((char *) (stack)->elements + (stack)->size * (n))) + +ZEND_API int zend_stack_init(zend_stack *stack, int size) { + stack->size = size; stack->top = 0; stack->max = 0; stack->elements = NULL; return SUCCESS; } -ZEND_API int zend_stack_push(zend_stack *stack, const void *element, int size) +ZEND_API int zend_stack_push(zend_stack *stack, const void *element) { - if (stack->top >= stack->max) { /* we need to allocate more memory */ - stack->elements = (void **) erealloc(stack->elements, - (sizeof(void **) * (stack->max += STACK_BLOCK_SIZE))); - if (!stack->elements) { - return FAILURE; - } + /* We need to allocate more memory */ + if (stack->top >= stack->max) { + stack->max += STACK_BLOCK_SIZE; + stack->elements = safe_erealloc(stack->elements, stack->size, stack->max, 0); } - stack->elements[stack->top] = (void *) emalloc(size); - memcpy(stack->elements[stack->top], element, size); + memcpy(ZEND_STACK_ELEMENT(stack, stack->top), element, stack->size); return stack->top++; } -ZEND_API int zend_stack_top(const zend_stack *stack, void **element) +ZEND_API void *zend_stack_top(const zend_stack *stack) { if (stack->top > 0) { - *element = stack->elements[stack->top - 1]; - return SUCCESS; + return ZEND_STACK_ELEMENT(stack, stack->top - 1); } else { - *element = NULL; - return FAILURE; + return NULL; } } ZEND_API int zend_stack_del_top(zend_stack *stack) { - if (stack->top > 0) { - efree(stack->elements[--stack->top]); - } + --stack->top; return SUCCESS; } ZEND_API int zend_stack_int_top(const zend_stack *stack) { - int *e; - - if (zend_stack_top(stack, (void **) &e) == FAILURE) { - return FAILURE; /* this must be a negative number, since negative numbers can't be address numbers */ - } else { + int *e = zend_stack_top(stack); + if (e) { return *e; + } else { + return FAILURE; } } ZEND_API int zend_stack_is_empty(const zend_stack *stack) { - if (stack->top == 0) { - return 1; - } else { - return 0; - } + return stack->top == 0; } ZEND_API int zend_stack_destroy(zend_stack *stack) { - int i; - if (stack->elements) { - for (i = 0; i < stack->top; i++) { - efree(stack->elements[i]); - } efree(stack->elements); stack->elements = NULL; } @@ -104,7 +90,7 @@ ZEND_API int zend_stack_destroy(zend_stack *stack) } -ZEND_API void **zend_stack_base(const zend_stack *stack) +ZEND_API void *zend_stack_base(const zend_stack *stack) { return stack->elements; } @@ -123,14 +109,14 @@ ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function switch (type) { case ZEND_STACK_APPLY_TOPDOWN: for (i=stack->top-1; i>=0; i--) { - if (apply_function(stack->elements[i])) { + if (apply_function(ZEND_STACK_ELEMENT(stack, i))) { break; } } break; case ZEND_STACK_APPLY_BOTTOMUP: for (i=0; i<stack->top; i++) { - if (apply_function(stack->elements[i])) { + if (apply_function(ZEND_STACK_ELEMENT(stack, i))) { break; } } @@ -146,14 +132,14 @@ ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (* switch (type) { case ZEND_STACK_APPLY_TOPDOWN: for (i=stack->top-1; i>=0; i--) { - if (apply_function(stack->elements[i], arg)) { + if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) { break; } } break; case ZEND_STACK_APPLY_BOTTOMUP: for (i=0; i<stack->top; i++) { - if (apply_function(stack->elements[i], arg)) { + if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) { break; } } @@ -161,6 +147,24 @@ ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (* } } +ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), zend_bool free_elements) +{ + int i; + + if (func) { + for (i = 0; i < stack->top; i++) { + func(ZEND_STACK_ELEMENT(stack, i)); + } + } + if (free_elements) { + if (stack->elements) { + efree(stack->elements); + stack->elements = NULL; + } + stack->top = stack->max = 0; + } +} + /* * Local variables: * tab-width: 4 |