]> granicus.if.org Git - php/commitdiff
Don't allocate zend_stack elements individually
authorNikita Popov <nikic@php.net>
Wed, 30 Apr 2014 18:28:02 +0000 (20:28 +0200)
committerNikita Popov <nikic@php.net>
Thu, 1 May 2014 07:08:29 +0000 (09:08 +0200)
Instead allocate a vector of elements. Size must now be specified
on initialization rather than on push.

Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_execute_API.c
Zend/zend_ini_scanner.c
Zend/zend_ini_scanner.l
Zend/zend_language_scanner.c
Zend/zend_language_scanner.l
Zend/zend_stack.c
Zend/zend_stack.h
main/output.c

index 80f3818d171c7c2c453e43d1caa1b48356d4f5e0..d858fe798242e401c470141a6e720dc1ea64fa4f 100644 (file)
@@ -1484,8 +1484,8 @@ ZEND_FUNCTION(set_error_handler)
        if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
                RETVAL_ZVAL(&EG(user_error_handler), 1, 0);
 
-               zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
-               zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler), sizeof(zval));
+               zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting));
+               zend_stack_push(&EG(user_error_handlers), &EG(user_error_handler));
        }
 
        if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
@@ -1550,7 +1550,7 @@ ZEND_FUNCTION(set_exception_handler)
        if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
                RETVAL_ZVAL(&EG(user_exception_handler), 1, 0);
 
-               zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler), sizeof(zval));
+               zend_stack_push(&EG(user_exception_handlers), &EG(user_exception_handler));
        }
 
        if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
index 02dca941baa6849e73f8b305f84dbc02e8021a36..232e9ae661511ea23813ea9414ab989eb9e01d3d 100644 (file)
@@ -100,7 +100,7 @@ ZEND_API zend_executor_globals executor_globals;
 static void zend_push_function_call_entry(zend_function *fbc TSRMLS_DC) /* {{{ */
 {
        zend_function_call_entry fcall = { fbc };
-       zend_stack_push(&CG(function_call_stack), &fcall, sizeof(zend_function_call_entry));
+       zend_stack_push(&CG(function_call_stack), &fcall);
 }
 /* }}} */
 
@@ -202,16 +202,16 @@ void zend_init_compiler_context(TSRMLS_D) /* {{{ */
 
 void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
 {
-       zend_stack_init(&CG(bp_stack));
-       zend_stack_init(&CG(function_call_stack));
-       zend_stack_init(&CG(switch_cond_stack));
-       zend_stack_init(&CG(foreach_copy_stack));
-       zend_stack_init(&CG(object_stack));
-       zend_stack_init(&CG(declare_stack));
+       zend_stack_init(&CG(bp_stack), sizeof(zend_llist));
+       zend_stack_init(&CG(function_call_stack), sizeof(zend_function_call_entry));
+       zend_stack_init(&CG(switch_cond_stack), sizeof(zend_switch_entry));
+       zend_stack_init(&CG(foreach_copy_stack), sizeof(zend_op));
+       zend_stack_init(&CG(object_stack), sizeof(znode));
+       zend_stack_init(&CG(declare_stack), sizeof(zend_declarables));
        CG(active_class_entry) = NULL;
        zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
        zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
-       zend_stack_init(&CG(list_stack));
+       zend_stack_init(&CG(list_stack), sizeof(zend_llist));
        CG(in_compilation) = 0;
        CG(start_lineno) = 0;
        ZVAL_UNDEF(&CG(current_namespace));
@@ -222,7 +222,7 @@ void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
        CG(current_import_const) = NULL;
        zend_hash_init(&CG(const_filenames), 8, NULL, NULL, 0);
        init_compiler_declarables(TSRMLS_C);
-       zend_stack_init(&CG(context_stack));
+       zend_stack_init(&CG(context_stack), sizeof(CG(context)));
 
        CG(encoding_declared) = 0;
 }
@@ -1243,7 +1243,7 @@ void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned cha
                zend_llist jmp_list;
 
                zend_llist_init(&jmp_list, sizeof(int), NULL, 0);
-               zend_stack_push(&CG(bp_stack), (void *) &jmp_list, sizeof(zend_llist));
+               zend_stack_push(&CG(bp_stack), (void *) &jmp_list);
        }
        zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
        zend_llist_add_element(jmp_list_ptr, &if_end_op_number);
@@ -1288,7 +1288,7 @@ void zend_do_begin_variable_parse(TSRMLS_D) /* {{{ */
        zend_llist fetch_list;
 
        zend_llist_init(&fetch_list, sizeof(zend_op), NULL, 0);
-       zend_stack_push(&CG(bp_stack), (void *) &fetch_list, sizeof(zend_llist));
+       zend_stack_push(&CG(bp_stack), (void *) &fetch_list);
 }
 /* }}} */
 
@@ -1574,7 +1574,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
                        zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_class_entry)->name->val, name->val);
                }
 
-               zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
+               zend_stack_push(&CG(context_stack), (void *) &CG(context));
                zend_init_compiler_context(TSRMLS_C);
 
                if (fn_flags & ZEND_ACC_ABSTRACT) {
@@ -1737,7 +1737,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
                CG(active_op_array) = emalloc(sizeof(zend_op_array));
                memcpy(CG(active_op_array), &op_array, sizeof(zend_op_array));
                zend_hash_update_ptr(CG(function_table), Z_STR(key), CG(active_op_array));
-               zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
+               zend_stack_push(&CG(context_stack), (void *) &CG(context));
                zend_init_compiler_context(TSRMLS_C);
                STR_RELEASE(lcname);
        }
@@ -1759,7 +1759,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
                switch_entry.default_case = 0;
                switch_entry.control_var = 0;
 
-               zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
+               zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry);
        }
 
        {
@@ -1768,7 +1768,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
 
                dummy_opline.result_type = IS_UNUSED;
 
-               zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
+               zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline);
        }
 
        if (CG(doc_comment)) {
@@ -2938,7 +2938,7 @@ void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC) /* {{{ */
        /* save for backpatching */
 
        zend_llist_init(&jmp_list, sizeof(int), NULL, 0);
-       zend_stack_push(&CG(bp_stack), (void *) &jmp_list, sizeof(zend_llist));
+       zend_stack_push(&CG(bp_stack), (void *) &jmp_list);
        zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
        zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
 
@@ -4995,7 +4995,7 @@ void zend_do_switch_cond(const znode *cond TSRMLS_DC) /* {{{ */
        switch_entry.cond = *cond;
        switch_entry.default_case = -1;
        switch_entry.control_var = -1;
-       zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
+       zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry);
 
        do_begin_loop(TSRMLS_C);
 
@@ -5607,7 +5607,7 @@ void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */
 
 void zend_do_push_object(const znode *object TSRMLS_DC) /* {{{ */
 {
-       zend_stack_push(&CG(object_stack), object, sizeof(znode));
+       zend_stack_push(&CG(object_stack), object);
 }
 /* }}} */
 
@@ -6023,8 +6023,8 @@ void zend_do_new_list_end(TSRMLS_D) /* {{{ */
 
 void zend_do_list_init(TSRMLS_D) /* {{{ */
 {
-       zend_stack_push(&CG(list_stack), &CG(list_llist), sizeof(zend_llist));
-       zend_stack_push(&CG(list_stack), &CG(dimension_llist), sizeof(zend_llist));
+       zend_stack_push(&CG(list_stack), &CG(list_llist));
+       zend_stack_push(&CG(list_stack), &CG(dimension_llist));
        zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
        zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
        zend_do_new_list_begin(TSRMLS_C);
@@ -6422,7 +6422,7 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno
        opline->extended_value = is_variable ? ZEND_FE_RESET_VARIABLE : 0;
 
        COPY_NODE(dummy_opline.result, opline->result);
-       zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
+       zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline);
 
        /* save the location of FE_FETCH */
        as_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
@@ -6563,7 +6563,7 @@ void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRML
 
 void zend_do_declare_begin(TSRMLS_D) /* {{{ */
 {
-       zend_stack_push(&CG(declare_stack), &CG(declarables), sizeof(zend_declarables));
+       zend_stack_push(&CG(declare_stack), &CG(declarables));
 }
 /* }}} */
 
index 7041563704f8c2556a876cc5e3537f4f3c800af9..ff52993ca007999806b96ad9f5ca39ac9dddfc35 100644 (file)
@@ -174,9 +174,9 @@ void init_executor(TSRMLS_D) /* {{{ */
 
        EG(current_execute_data) = NULL;
 
-       zend_stack_init(&EG(user_error_handlers_error_reporting));
-       zend_stack_init(&EG(user_error_handlers));
-       zend_stack_init(&EG(user_exception_handlers));
+       zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int));
+       zend_stack_init(&EG(user_error_handlers), sizeof(zval));
+       zend_stack_init(&EG(user_exception_handlers), sizeof(zval));
 
        zend_objects_store_init(&EG(objects_store), 1024);
 
@@ -289,8 +289,7 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
                        ZVAL_UNDEF(&EG(user_exception_handler));
                }
 
-               zend_stack_destroy(&EG(user_error_handlers_error_reporting));
-               zend_stack_init(&EG(user_error_handlers_error_reporting));
+               zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
                zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1);
                zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1);
        } zend_end_try();
index 311788fbbfbec0c583e659d393758400353e9228..9ade1497d857dcf6ecc9e6f1495d36f7220981c1 100644 (file)
@@ -144,7 +144,7 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
 
 static void _yy_push_state(int new_state TSRMLS_DC)
 {
-       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
+       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION());
        YYSETCONDITION(new_state);
 }
 
@@ -187,7 +187,7 @@ static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
                ini_filename = NULL;
        }
 
-       zend_stack_init(&SCNG(state_stack));
+       zend_stack_init(&SCNG(state_stack), sizeof(int));
        BEGIN(INITIAL);
 
        return SUCCESS;
index 379d86965d5cf3cb9b09bdfa73f217924788acd7..1b3cbd47ea07fb02fda0d3aa17e29c2a05f48648 100644 (file)
@@ -142,7 +142,7 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
 
 static void _yy_push_state(int new_state TSRMLS_DC)
 {
-       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
+       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION());
        YYSETCONDITION(new_state);
 }
 
@@ -185,7 +185,7 @@ static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
                ini_filename = NULL;
        }
 
-       zend_stack_init(&SCNG(state_stack));
+       zend_stack_init(&SCNG(state_stack), sizeof(int));
        BEGIN(INITIAL);
 
        return SUCCESS;
index be8be6c782b222a96eed285c224779abdc8c1e74..5f384680eee8f3519c4052c2e2af93c7d58aa551 100644 (file)
@@ -154,7 +154,7 @@ internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC);
 
 static void _yy_push_state(int new_state TSRMLS_DC)
 {
-       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
+       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION());
        YYSETCONDITION(new_state);
 }
 
@@ -181,7 +181,7 @@ void startup_scanner(TSRMLS_D)
 {
        CG(parse_error) = 0;
        CG(doc_comment) = NULL;
-       zend_stack_init(&SCNG(state_stack));
+       zend_stack_init(&SCNG(state_stack), sizeof(int));
        zend_ptr_stack_init(&SCNG(heredoc_label_stack));
 }
 
@@ -208,7 +208,7 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        lex_state->yy_limit  = SCNG(yy_limit);
 
        lex_state->state_stack = SCNG(state_stack);
-       zend_stack_init(&SCNG(state_stack));
+       zend_stack_init(&SCNG(state_stack), sizeof(int));
 
        lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
        zend_ptr_stack_init(&SCNG(heredoc_label_stack));
@@ -584,7 +584,7 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
                init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
                CG(in_compilation) = 1;
                CG(active_op_array) = op_array;
-               zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
+               zend_stack_push(&CG(context_stack), (void *) &CG(context));
                zend_init_compiler_context(TSRMLS_C);
                compiler_result = zendparse(TSRMLS_C);
                zend_do_return(&retval_znode, 0 TSRMLS_CC);
@@ -750,7 +750,7 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
                init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
                CG(interactive) = orig_interactive;
                CG(active_op_array) = op_array;
-               zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
+               zend_stack_push(&CG(context_stack), (void *) &CG(context));
                zend_init_compiler_context(TSRMLS_C);
                BEGIN(ST_IN_SCRIPTING);
                compiler_result = zendparse(TSRMLS_C);
index 2204adf064694c916c31a37cdfa4415f7a73f643..71e9bb60ab01576fd1883ed82a3fa470a52270ea 100644 (file)
@@ -152,7 +152,7 @@ internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC);
 
 static void _yy_push_state(int new_state TSRMLS_DC)
 {
-       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
+       zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION());
        YYSETCONDITION(new_state);
 }
 
@@ -179,7 +179,7 @@ void startup_scanner(TSRMLS_D)
 {
        CG(parse_error) = 0;
        CG(doc_comment) = NULL;
-       zend_stack_init(&SCNG(state_stack));
+       zend_stack_init(&SCNG(state_stack), sizeof(int));
        zend_ptr_stack_init(&SCNG(heredoc_label_stack));
 }
 
@@ -206,7 +206,7 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
        lex_state->yy_limit  = SCNG(yy_limit);
 
        lex_state->state_stack = SCNG(state_stack);
-       zend_stack_init(&SCNG(state_stack));
+       zend_stack_init(&SCNG(state_stack), sizeof(int));
 
        lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
        zend_ptr_stack_init(&SCNG(heredoc_label_stack));
@@ -582,7 +582,7 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
                init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
                CG(in_compilation) = 1;
                CG(active_op_array) = op_array;
-               zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
+               zend_stack_push(&CG(context_stack), (void *) &CG(context));
                zend_init_compiler_context(TSRMLS_C);
                compiler_result = zendparse(TSRMLS_C);
                zend_do_return(&retval_znode, 0 TSRMLS_CC);
@@ -748,7 +748,7 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
                init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
                CG(interactive) = orig_interactive;
                CG(active_op_array) = op_array;
-               zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context)));
+               zend_stack_push(&CG(context_stack), (void *) &CG(context));
                zend_init_compiler_context(TSRMLS_C);
                BEGIN(ST_IN_SCRIPTING);
                compiler_result = zendparse(TSRMLS_C);
index 31bb8afec5eceea1d18151b325be195c61941ca1..a3c8759f1c86ba8ad855e7935ef8de74b6cb97f8 100644 (file)
 #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++;
 }
 
@@ -48,7 +48,7 @@ ZEND_API int zend_stack_push(zend_stack *stack, const void *element, int size)
 ZEND_API int zend_stack_top(const zend_stack *stack, void **element)
 {
        if (stack->top > 0) {
-               *element = stack->elements[stack->top - 1];
+               *element = ZEND_STACK_ELEMENT(stack, stack->top - 1);
                return SUCCESS;
        } else {
                *element = NULL;
@@ -59,9 +59,7 @@ ZEND_API int zend_stack_top(const zend_stack *stack, void **element)
 
 ZEND_API int zend_stack_del_top(zend_stack *stack)
 {
-       if (stack->top > 0) {
-               efree(stack->elements[--stack->top]);
-       }
+       --stack->top;
        return SUCCESS;
 }
 
@@ -71,7 +69,8 @@ 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 */
+               /* this must be a negative number, since negative numbers can't be address numbers */
+               return FAILURE;
        } else {
                return *e;
        }
@@ -80,22 +79,13 @@ ZEND_API int zend_stack_int_top(const zend_stack *stack)
 
 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 +94,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 +113,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 +136,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;
                                }
                        }
@@ -167,14 +157,11 @@ ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), zend_boo
 
        if (func) {
                for (i = 0; i < stack->top; i++) {
-                       func(stack->elements[i]);
+                       func(ZEND_STACK_ELEMENT(stack, i));
                }
        }
        if (free_elements) {
                if (stack->elements) {
-                       for (i = 0; i < stack->top; i++) {
-                               efree(stack->elements[i]);
-                       }
                        efree(stack->elements);
                        stack->elements = NULL;
                }
index 851e2301aa993e918c8c6fac2a078e9c541199cd..3932136aacd75325b46b12c26de1d2d060f5aed5 100644 (file)
 #define ZEND_STACK_H
 
 typedef struct _zend_stack {
-       int top, max;
-       void **elements;
+       int size, top, max;
+       void *elements;
 } zend_stack;
 
 
-#define STACK_BLOCK_SIZE 64
+#define STACK_BLOCK_SIZE 16
 
 BEGIN_EXTERN_C()
-ZEND_API int zend_stack_init(zend_stack *stack);
-ZEND_API int zend_stack_push(zend_stack *stack, const void *element, int size);
+ZEND_API int zend_stack_init(zend_stack *stack, int size);
+ZEND_API int zend_stack_push(zend_stack *stack, const void *element);
 ZEND_API int zend_stack_top(const zend_stack *stack, void **element);
 ZEND_API int zend_stack_del_top(zend_stack *stack);
 ZEND_API int zend_stack_int_top(const zend_stack *stack);
 ZEND_API int zend_stack_is_empty(const zend_stack *stack);
 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);
 ZEND_API int zend_stack_count(const zend_stack *stack);
 ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element));
 ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg);
index 3dd647a9b263bb5d869cd5b8b0dd0780ed69be47..6c6fa5ca8a36bdb0b3e9021b6832afdbbc5ae5ec 100644 (file)
@@ -165,7 +165,7 @@ PHPAPI int php_output_activate(TSRMLS_D)
        memset(&output_globals, 0, sizeof(zend_output_globals));
 #endif
 
-       zend_stack_init(&OG(handlers));
+       zend_stack_init(&OG(handlers), sizeof(php_output_handler *));
        OG(flags) |= PHP_OUTPUT_ACTIVATED;
 
        return SUCCESS;
@@ -291,7 +291,7 @@ PHPAPI int php_output_flush(TSRMLS_D)
                if (context.out.data && context.out.used) {
                        zend_stack_del_top(&OG(handlers));
                        php_output_write(context.out.data, context.out.used TSRMLS_CC);
-                       zend_stack_push(&OG(handlers), &OG(active), sizeof(php_output_handler *));
+                       zend_stack_push(&OG(handlers), &OG(active));
                }
                php_output_context_dtor(&context);
                return SUCCESS;
@@ -578,10 +578,8 @@ PHPAPI int php_output_handler_start(php_output_handler *handler TSRMLS_DC)
                        }
                }
        }
-       /* zend_stack_push never returns SUCCESS but FAILURE or stack level */
-       if (FAILURE == (handler->level = zend_stack_push(&OG(handlers), &handler, sizeof(php_output_handler *)))) {
-               return FAILURE;
-       }
+       /* zend_stack_push returns stack level */
+       handler->level = zend_stack_push(&OG(handlers), &handler);
        OG(active) = handler;
        return SUCCESS;
 }
@@ -591,14 +589,14 @@ PHPAPI int php_output_handler_start(php_output_handler *handler TSRMLS_DC)
  * Check whether a certain output handler is in use */
 PHPAPI int php_output_handler_started(const char *name, size_t name_len TSRMLS_DC)
 {
-       php_output_handler ***handlers;
+       php_output_handler **handlers;
        int i, count = php_output_get_level(TSRMLS_C);
 
        if (count) {
-               handlers = (php_output_handler ***) zend_stack_base(&OG(handlers));
+               handlers = (php_output_handler **) zend_stack_base(&OG(handlers));
 
                for (i = 0; i < count; ++i) {
-                       if (name_len == (*(handlers[i]))->name_len && !memcmp((*(handlers[i]))->name, name, name_len)) {
+                       if (name_len == handlers[i]->name_len && !memcmp(handlers[i]->name, name, name_len)) {
                                return 1;
                        }
                }