Don't allocate zend_stack elements individually

Instead allocate a vector of elements. Size must now be specified
on initialization rather than on push.
This commit is contained in:
Nikita Popov 2014-04-30 20:28:02 +02:00
parent 257bf697ae
commit 5a03efe279
10 changed files with 77 additions and 93 deletions

View file

@ -1484,8 +1484,8 @@ ZEND_FUNCTION(set_error_handler)
if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) { if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) {
RETVAL_ZVAL(&EG(user_error_handler), 1, 0); 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_error_reporting), &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), &EG(user_error_handler));
} }
if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined 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) { if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) {
RETVAL_ZVAL(&EG(user_exception_handler), 1, 0); 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 */ if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */

View file

@ -100,7 +100,7 @@ ZEND_API zend_executor_globals executor_globals;
static void zend_push_function_call_entry(zend_function *fbc TSRMLS_DC) /* {{{ */ static void zend_push_function_call_entry(zend_function *fbc TSRMLS_DC) /* {{{ */
{ {
zend_function_call_entry fcall = { fbc }; 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) /* {{{ */ void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
{ {
zend_stack_init(&CG(bp_stack)); zend_stack_init(&CG(bp_stack), sizeof(zend_llist));
zend_stack_init(&CG(function_call_stack)); zend_stack_init(&CG(function_call_stack), sizeof(zend_function_call_entry));
zend_stack_init(&CG(switch_cond_stack)); zend_stack_init(&CG(switch_cond_stack), sizeof(zend_switch_entry));
zend_stack_init(&CG(foreach_copy_stack)); zend_stack_init(&CG(foreach_copy_stack), sizeof(zend_op));
zend_stack_init(&CG(object_stack)); zend_stack_init(&CG(object_stack), sizeof(znode));
zend_stack_init(&CG(declare_stack)); zend_stack_init(&CG(declare_stack), sizeof(zend_declarables));
CG(active_class_entry) = NULL; CG(active_class_entry) = NULL;
zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0); zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
zend_llist_init(&CG(dimension_llist), sizeof(int), 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(in_compilation) = 0;
CG(start_lineno) = 0; CG(start_lineno) = 0;
ZVAL_UNDEF(&CG(current_namespace)); ZVAL_UNDEF(&CG(current_namespace));
@ -222,7 +222,7 @@ void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
CG(current_import_const) = NULL; CG(current_import_const) = NULL;
zend_hash_init(&CG(const_filenames), 8, NULL, NULL, 0); zend_hash_init(&CG(const_filenames), 8, NULL, NULL, 0);
init_compiler_declarables(TSRMLS_C); init_compiler_declarables(TSRMLS_C);
zend_stack_init(&CG(context_stack)); zend_stack_init(&CG(context_stack), sizeof(CG(context)));
CG(encoding_declared) = 0; 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 jmp_list;
zend_llist_init(&jmp_list, sizeof(int), NULL, 0); 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_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
zend_llist_add_element(jmp_list_ptr, &if_end_op_number); 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 fetch_list;
zend_llist_init(&fetch_list, sizeof(zend_op), NULL, 0); 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_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); zend_init_compiler_context(TSRMLS_C);
if (fn_flags & ZEND_ACC_ABSTRACT) { 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)); CG(active_op_array) = emalloc(sizeof(zend_op_array));
memcpy(CG(active_op_array), &op_array, 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_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); zend_init_compiler_context(TSRMLS_C);
STR_RELEASE(lcname); 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.default_case = 0;
switch_entry.control_var = 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; 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)) { if (CG(doc_comment)) {
@ -2938,7 +2938,7 @@ void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC) /* {{{ */
/* save for backpatching */ /* save for backpatching */
zend_llist_init(&jmp_list, sizeof(int), NULL, 0); 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_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
zend_llist_add_element(jmp_list_ptr, &jmp_op_number); 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.cond = *cond;
switch_entry.default_case = -1; switch_entry.default_case = -1;
switch_entry.control_var = -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); 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) /* {{{ */ 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) /* {{{ */ 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(list_llist));
zend_stack_push(&CG(list_stack), &CG(dimension_llist), sizeof(zend_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(list_llist), sizeof(list_llist_element), NULL, 0);
zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0); zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
zend_do_new_list_begin(TSRMLS_C); 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; opline->extended_value = is_variable ? ZEND_FE_RESET_VARIABLE : 0;
COPY_NODE(dummy_opline.result, opline->result); 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 */ /* save the location of FE_FETCH */
as_token->u.op.opline_num = get_next_op_number(CG(active_op_array)); 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) /* {{{ */ 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));
} }
/* }}} */ /* }}} */

View file

@ -174,9 +174,9 @@ void init_executor(TSRMLS_D) /* {{{ */
EG(current_execute_data) = NULL; EG(current_execute_data) = NULL;
zend_stack_init(&EG(user_error_handlers_error_reporting)); zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int));
zend_stack_init(&EG(user_error_handlers)); zend_stack_init(&EG(user_error_handlers), sizeof(zval));
zend_stack_init(&EG(user_exception_handlers)); zend_stack_init(&EG(user_exception_handlers), sizeof(zval));
zend_objects_store_init(&EG(objects_store), 1024); zend_objects_store_init(&EG(objects_store), 1024);
@ -289,8 +289,7 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
ZVAL_UNDEF(&EG(user_exception_handler)); ZVAL_UNDEF(&EG(user_exception_handler));
} }
zend_stack_destroy(&EG(user_error_handlers_error_reporting)); zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1);
zend_stack_init(&EG(user_error_handlers_error_reporting));
zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 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_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1);
} zend_end_try(); } zend_end_try();

View file

@ -144,7 +144,7 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
static void _yy_push_state(int new_state TSRMLS_DC) 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); YYSETCONDITION(new_state);
} }
@ -187,7 +187,7 @@ static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
ini_filename = NULL; ini_filename = NULL;
} }
zend_stack_init(&SCNG(state_stack)); zend_stack_init(&SCNG(state_stack), sizeof(int));
BEGIN(INITIAL); BEGIN(INITIAL);
return SUCCESS; return SUCCESS;

View file

@ -142,7 +142,7 @@ ZEND_API zend_ini_scanner_globals ini_scanner_globals;
static void _yy_push_state(int new_state TSRMLS_DC) 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); YYSETCONDITION(new_state);
} }
@ -185,7 +185,7 @@ static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC)
ini_filename = NULL; ini_filename = NULL;
} }
zend_stack_init(&SCNG(state_stack)); zend_stack_init(&SCNG(state_stack), sizeof(int));
BEGIN(INITIAL); BEGIN(INITIAL);
return SUCCESS; return SUCCESS;

View file

@ -154,7 +154,7 @@ internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC);
static void _yy_push_state(int new_state TSRMLS_DC) 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); YYSETCONDITION(new_state);
} }
@ -181,7 +181,7 @@ void startup_scanner(TSRMLS_D)
{ {
CG(parse_error) = 0; CG(parse_error) = 0;
CG(doc_comment) = NULL; 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)); 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->yy_limit = SCNG(yy_limit);
lex_state->state_stack = SCNG(state_stack); 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); lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
zend_ptr_stack_init(&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); init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
CG(in_compilation) = 1; CG(in_compilation) = 1;
CG(active_op_array) = op_array; 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); zend_init_compiler_context(TSRMLS_C);
compiler_result = zendparse(TSRMLS_C); compiler_result = zendparse(TSRMLS_C);
zend_do_return(&retval_znode, 0 TSRMLS_CC); 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); init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
CG(interactive) = orig_interactive; CG(interactive) = orig_interactive;
CG(active_op_array) = op_array; 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); zend_init_compiler_context(TSRMLS_C);
BEGIN(ST_IN_SCRIPTING); BEGIN(ST_IN_SCRIPTING);
compiler_result = zendparse(TSRMLS_C); compiler_result = zendparse(TSRMLS_C);

View file

@ -152,7 +152,7 @@ internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC);
static void _yy_push_state(int new_state TSRMLS_DC) 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); YYSETCONDITION(new_state);
} }
@ -179,7 +179,7 @@ void startup_scanner(TSRMLS_D)
{ {
CG(parse_error) = 0; CG(parse_error) = 0;
CG(doc_comment) = NULL; 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)); 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->yy_limit = SCNG(yy_limit);
lex_state->state_stack = SCNG(state_stack); 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); lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
zend_ptr_stack_init(&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); init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
CG(in_compilation) = 1; CG(in_compilation) = 1;
CG(active_op_array) = op_array; 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); zend_init_compiler_context(TSRMLS_C);
compiler_result = zendparse(TSRMLS_C); compiler_result = zendparse(TSRMLS_C);
zend_do_return(&retval_znode, 0 TSRMLS_CC); 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); init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
CG(interactive) = orig_interactive; CG(interactive) = orig_interactive;
CG(active_op_array) = op_array; 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); zend_init_compiler_context(TSRMLS_C);
BEGIN(ST_IN_SCRIPTING); BEGIN(ST_IN_SCRIPTING);
compiler_result = zendparse(TSRMLS_C); compiler_result = zendparse(TSRMLS_C);

View file

@ -22,25 +22,25 @@
#include "zend.h" #include "zend.h"
#include "zend_stack.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->top = 0;
stack->max = 0; stack->max = 0;
stack->elements = NULL; stack->elements = NULL;
return SUCCESS; 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 */ /* We need to allocate more memory */
stack->elements = (void **) erealloc(stack->elements, if (stack->top >= stack->max) {
(sizeof(void **) * (stack->max += STACK_BLOCK_SIZE))); stack->max += STACK_BLOCK_SIZE;
if (!stack->elements) { stack->elements = safe_erealloc(stack->elements, stack->size, stack->max, 0);
return FAILURE;
}
} }
stack->elements[stack->top] = (void *) emalloc(size); memcpy(ZEND_STACK_ELEMENT(stack, stack->top), element, stack->size);
memcpy(stack->elements[stack->top], element, size);
return stack->top++; 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) ZEND_API int zend_stack_top(const zend_stack *stack, void **element)
{ {
if (stack->top > 0) { if (stack->top > 0) {
*element = stack->elements[stack->top - 1]; *element = ZEND_STACK_ELEMENT(stack, stack->top - 1);
return SUCCESS; return SUCCESS;
} else { } else {
*element = NULL; *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) ZEND_API int zend_stack_del_top(zend_stack *stack)
{ {
if (stack->top > 0) { --stack->top;
efree(stack->elements[--stack->top]);
}
return SUCCESS; return SUCCESS;
} }
@ -71,7 +69,8 @@ ZEND_API int zend_stack_int_top(const zend_stack *stack)
int *e; int *e;
if (zend_stack_top(stack, (void **) &e) == FAILURE) { 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 { } else {
return *e; 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) ZEND_API int zend_stack_is_empty(const zend_stack *stack)
{ {
if (stack->top == 0) { return stack->top == 0;
return 1;
} else {
return 0;
}
} }
ZEND_API int zend_stack_destroy(zend_stack *stack) ZEND_API int zend_stack_destroy(zend_stack *stack)
{ {
int i;
if (stack->elements) { if (stack->elements) {
for (i = 0; i < stack->top; i++) {
efree(stack->elements[i]);
}
efree(stack->elements); efree(stack->elements);
stack->elements = NULL; 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; return stack->elements;
} }
@ -123,14 +113,14 @@ ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function
switch (type) { switch (type) {
case ZEND_STACK_APPLY_TOPDOWN: case ZEND_STACK_APPLY_TOPDOWN:
for (i=stack->top-1; i>=0; i--) { for (i=stack->top-1; i>=0; i--) {
if (apply_function(stack->elements[i])) { if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
break; break;
} }
} }
break; break;
case ZEND_STACK_APPLY_BOTTOMUP: case ZEND_STACK_APPLY_BOTTOMUP:
for (i=0; i<stack->top; i++) { for (i=0; i<stack->top; i++) {
if (apply_function(stack->elements[i])) { if (apply_function(ZEND_STACK_ELEMENT(stack, i))) {
break; break;
} }
} }
@ -146,14 +136,14 @@ ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*
switch (type) { switch (type) {
case ZEND_STACK_APPLY_TOPDOWN: case ZEND_STACK_APPLY_TOPDOWN:
for (i=stack->top-1; i>=0; i--) { 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;
} }
} }
break; break;
case ZEND_STACK_APPLY_BOTTOMUP: case ZEND_STACK_APPLY_BOTTOMUP:
for (i=0; i<stack->top; i++) { for (i=0; i<stack->top; i++) {
if (apply_function(stack->elements[i], arg)) { if (apply_function(ZEND_STACK_ELEMENT(stack, i), arg)) {
break; break;
} }
} }
@ -167,14 +157,11 @@ ZEND_API void zend_stack_clean(zend_stack *stack, void (*func)(void *), zend_boo
if (func) { if (func) {
for (i = 0; i < stack->top; i++) { for (i = 0; i < stack->top; i++) {
func(stack->elements[i]); func(ZEND_STACK_ELEMENT(stack, i));
} }
} }
if (free_elements) { if (free_elements) {
if (stack->elements) { if (stack->elements) {
for (i = 0; i < stack->top; i++) {
efree(stack->elements[i]);
}
efree(stack->elements); efree(stack->elements);
stack->elements = NULL; stack->elements = NULL;
} }

View file

@ -23,22 +23,22 @@
#define ZEND_STACK_H #define ZEND_STACK_H
typedef struct _zend_stack { typedef struct _zend_stack {
int top, max; int size, top, max;
void **elements; void *elements;
} zend_stack; } zend_stack;
#define STACK_BLOCK_SIZE 64 #define STACK_BLOCK_SIZE 16
BEGIN_EXTERN_C() BEGIN_EXTERN_C()
ZEND_API int zend_stack_init(zend_stack *stack); ZEND_API int zend_stack_init(zend_stack *stack, int size);
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);
ZEND_API int zend_stack_top(const zend_stack *stack, 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_del_top(zend_stack *stack);
ZEND_API int zend_stack_int_top(const 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_is_empty(const zend_stack *stack);
ZEND_API int zend_stack_destroy(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 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(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); ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg);

View file

@ -165,7 +165,7 @@ PHPAPI int php_output_activate(TSRMLS_D)
memset(&output_globals, 0, sizeof(zend_output_globals)); memset(&output_globals, 0, sizeof(zend_output_globals));
#endif #endif
zend_stack_init(&OG(handlers)); zend_stack_init(&OG(handlers), sizeof(php_output_handler *));
OG(flags) |= PHP_OUTPUT_ACTIVATED; OG(flags) |= PHP_OUTPUT_ACTIVATED;
return SUCCESS; return SUCCESS;
@ -291,7 +291,7 @@ PHPAPI int php_output_flush(TSRMLS_D)
if (context.out.data && context.out.used) { if (context.out.data && context.out.used) {
zend_stack_del_top(&OG(handlers)); zend_stack_del_top(&OG(handlers));
php_output_write(context.out.data, context.out.used TSRMLS_CC); 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); php_output_context_dtor(&context);
return SUCCESS; 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 */ /* zend_stack_push returns stack level */
if (FAILURE == (handler->level = zend_stack_push(&OG(handlers), &handler, sizeof(php_output_handler *)))) { handler->level = zend_stack_push(&OG(handlers), &handler);
return FAILURE;
}
OG(active) = handler; OG(active) = handler;
return SUCCESS; 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 */ * Check whether a certain output handler is in use */
PHPAPI int php_output_handler_started(const char *name, size_t name_len TSRMLS_DC) 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); int i, count = php_output_get_level(TSRMLS_C);
if (count) { 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) { 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; return 1;
} }
} }