diff options
Diffstat (limited to 'Zend')
| -rw-r--r-- | Zend/zend_builtin_functions.c | 26 | ||||
| -rw-r--r-- | Zend/zend_execute_API.c | 6 | ||||
| -rw-r--r-- | Zend/zend_globals.h | 1 | ||||
| -rw-r--r-- | Zend/zend_ptr_stack.c | 13 | ||||
| -rw-r--r-- | Zend/zend_ptr_stack.h | 3 |
5 files changed, 43 insertions, 6 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index d9d8ad3973..32ecc6f0b8 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -54,6 +54,7 @@ static ZEND_FUNCTION(get_object_vars); static ZEND_FUNCTION(get_class_methods); static ZEND_FUNCTION(trigger_error); static ZEND_FUNCTION(set_error_handler); +static ZEND_FUNCTION(restore_error_handler); static ZEND_FUNCTION(get_declared_classes); static ZEND_FUNCTION(create_function); #if ZEND_DEBUG @@ -96,6 +97,7 @@ static zend_function_entry builtin_functions[] = { ZEND_FE(trigger_error, NULL) ZEND_FALIAS(user_error, trigger_error, NULL) ZEND_FE(set_error_handler, NULL) + ZEND_FE(restore_error_handler, NULL) ZEND_FE(get_declared_classes, NULL) ZEND_FE(create_function, NULL) #if ZEND_DEBUG @@ -770,9 +772,10 @@ ZEND_FUNCTION(set_error_handler) if (EG(user_error_handler)) { had_orig_error_handler = 1; *return_value = *EG(user_error_handler); - } else { - ALLOC_ZVAL(EG(user_error_handler)); + zval_copy_ctor(return_value); + zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler)); } + ALLOC_ZVAL(EG(user_error_handler)); if (Z_STRLEN_PP(error_handler)==0) { /* unset user-defined handler */ FREE_ZVAL(EG(user_error_handler)); @@ -784,12 +787,29 @@ ZEND_FUNCTION(set_error_handler) zval_copy_ctor(EG(user_error_handler)); if (!had_orig_error_handler) { - RETURN_STRINGL("", 0, 1); + RETURN_NULL(); } } /* }}} */ + +/* {{{ proto void restore_error_handler(void) + Restores the previously defined error handler function */ +ZEND_FUNCTION(restore_error_handler) +{ + if (EG(user_error_handler)) { + zval_ptr_dtor(&EG(user_error_handler)); + } + if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) { + EG(user_error_handler) = NULL; + } else { + EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers)); + } + RETURN_TRUE; +} + + static int copy_class_name(zend_class_entry *ce, int num_args, va_list args, zend_hash_key *hash_key) { zval *array = va_arg(args, zval *); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1ff6bd937e..4d311581e7 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -143,6 +143,8 @@ void init_executor(CLS_D ELS_DC) EG(user_error_handler) = NULL; + zend_ptr_stack_init(&EG(user_error_handlers)); + #ifdef ZEND_WIN32 EG(timed_out) = 0; #endif @@ -173,7 +175,6 @@ void shutdown_executor(ELS_D) } } - zend_ptr_stack_destroy(&EG(argument_stack)); /* Destroy all op arrays */ @@ -199,6 +200,9 @@ void shutdown_executor(ELS_D) zval_dtor(EG(user_error_handler)); FREE_ZVAL(EG(user_error_handler)); } + + zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1); + zend_ptr_stack_destroy(&EG(user_error_handlers)); } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 4413c34b42..01e344fa96 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -183,6 +183,7 @@ struct _zend_executor_globals { int garbage_ptr; zval *user_error_handler; + zend_ptr_stack user_error_handlers; /* timeout support */ int timeout_seconds; diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c index ec9b448bfe..1bcfa6f593 100644 --- a/Zend/zend_ptr_stack.c +++ b/Zend/zend_ptr_stack.c @@ -104,11 +104,22 @@ ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *)) } -ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *)) +ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements) { zend_ptr_stack_apply(stack, func); + if (free_elements) { + int i = stack->top; + + while (--i >= 0) { + efree(stack->elements[i]); + } + } stack->top = 0; stack->top_element = stack->elements; } +ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack) +{ + return stack->top; +} diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h index ef607c55a0..d15268829b 100644 --- a/Zend/zend_ptr_stack.h +++ b/Zend/zend_ptr_stack.h @@ -37,6 +37,7 @@ ZEND_API void *zend_ptr_stack_pop(zend_ptr_stack *stack); ZEND_API void zend_ptr_stack_n_pop(zend_ptr_stack *stack, int count, ...); ZEND_API void zend_ptr_stack_destroy(zend_ptr_stack *stack); ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *)); -ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *)); +ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements); +ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack); #endif /* _ZEND_PTR_STACK_H */ |
