Improve bailout mechanism, supports nesting of bailouts a-la try..catch

This commit is contained in:
Zeev Suraski 2001-07-21 14:25:27 +00:00
parent 660a09c6da
commit 931ebe08d7
5 changed files with 51 additions and 20 deletions

View File

@ -464,11 +464,15 @@ void zenderror(char *error)
BEGIN_EXTERN_C()
ZEND_API void zend_bailout()
ZEND_API void _zend_bailout(ZEND_FILE_LINE_D)
{
CLS_FETCH();
ELS_FETCH();
if (!EG(bailout_set)) {
zend_output_debug_string(1, "%s(%d) : Bailed out without a bailout address!", ZEND_FILE_LINE_RELAY_C);
exit(-1);
}
CG(unclean_shutdown) = 1;
CG(in_compilation) = EG(in_execution) = 0;
longjmp(EG(bailout), FAILURE);
@ -506,6 +510,7 @@ ZEND_API char *get_zend_version()
void zend_activate(CLS_D ELS_DC)
{
EG(bailout_set) = 0;
init_compiler(CLS_C ELS_CC);
init_executor(CLS_C ELS_CC);
startup_scanner(CLS_C);
@ -522,9 +527,9 @@ void zend_deactivate_modules()
ELS_FETCH();
EG(opline_ptr) = NULL; /* we're no longer executing anything */
if (setjmp(EG(bailout))==0) {
zend_try {
zend_hash_apply(&module_registry, (int (*)(void *)) module_registry_cleanup);
}
} zend_end_try();
}
void zend_deactivate(CLS_D ELS_DC)
@ -533,17 +538,20 @@ void zend_deactivate(CLS_D ELS_DC)
EG(opline_ptr) = NULL;
EG(active_symbol_table) = NULL;
if (setjmp(EG(bailout))==0) {
zend_try {
shutdown_scanner(CLS_C);
}
} zend_end_try();
/* shutdown_executor() takes care of its own bailout handling */
shutdown_executor(ELS_C);
if (setjmp(EG(bailout))==0) {
zend_try {
shutdown_compiler(CLS_C);
}
if (setjmp(EG(bailout))==0) {
} zend_end_try();
zend_try {
zend_ini_deactivate(ELS_C);
}
} zend_end_try();
}

View File

@ -305,18 +305,40 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
void zend_shutdown(void);
void zend_set_utility_values(zend_utility_values *utility_values);
BEGIN_EXTERN_C()
ZEND_API void zend_bailout(void);
END_EXTERN_C()
ZEND_API char *get_zend_version(void);
BEGIN_EXTERN_C()
ZEND_API void _zend_bailout(ZEND_FILE_LINE_D);
END_EXTERN_C()
#if ZEND_DEBUG
#define zend_bailout() _zend_bailout(ZEND_FILE_LINE_C)
#else
#define zend_bailout() _zend_bailout()
#endif
#define zend_try \
{ \
jmp_buf orig_bailout; \
zend_bool orig_bailout_set=EG(bailout_set); \
\
EG(bailout_set) = 1; \
memcpy(&orig_bailout, &EG(bailout), sizeof(jmp_buf)); \
if (setjmp(EG(bailout))==0)
#define zend_catch \
else
#define zend_end_try() \
memcpy(&EG(bailout), &orig_bailout, sizeof(jmp_buf)); \
EG(bailout_set) = orig_bailout_set; \
}
ZEND_API char *get_zend_version(void);
ZEND_API void zend_make_printable_zval(zval *expr, zval *expr_copy, int *use_copy);
ZEND_API int zend_print_zval(zval *expr, int indent);
ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent);
ZEND_API void zend_print_zval_r(zval *expr, int indent);
ZEND_API void zend_print_zval_r_ex(zend_write_func_t write_func, zval *expr, int indent);
ZEND_API void zend_output_debug_string(zend_bool trigger_break, char *format, ...);
#if ZEND_DEBUG
#define Z_DBG(expr) (expr)
#else

View File

@ -152,7 +152,7 @@ void init_executor(CLS_D ELS_DC)
void shutdown_executor(ELS_D)
{
if (setjmp(EG(bailout))==0) {
zend_try {
zend_ptr_stack_destroy(&EG(arg_types_stack));
while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
@ -175,13 +175,13 @@ void shutdown_executor(ELS_D)
/* Destroy all op arrays */
zend_hash_apply(EG(function_table), (int (*)(void *)) is_not_internal_function);
zend_hash_apply(EG(class_table), (int (*)(void *)) is_not_internal_class);
}
} zend_end_try();
zend_destroy_rsrc_list(ELS_C); /* must be destroyed after the main symbol table and
* op arrays are destroyed.
*/
if (setjmp(EG(bailout))==0) {
zend_try {
clean_non_persistent_constants();
#if ZEND_DEBUG
signal(SIGSEGV, original_sigsegv_handler);
@ -198,7 +198,7 @@ void shutdown_executor(ELS_D)
zend_ptr_stack_destroy(&EG(user_error_handlers));
EG(error_reporting) = EG(orig_error_reporting);
}
} zend_end_try();
}

View File

@ -169,6 +169,7 @@ struct _zend_executor_globals {
int ticks_count;
zend_bool in_execution;
zend_bool bailout_set;
/* for extended information support */
zend_bool no_extensions;

View File

@ -246,9 +246,9 @@ void zend_destroy_rsrc_list(ELS_D)
ht->pListTail = q;
if (ht->pDestructor) {
if (setjmp(EG(bailout))==0) {
zend_try {
ht->pDestructor(p->pData);
}
} zend_end_try();
}
if (!p->pDataPtr && p->pData) {
pefree(p->pData, ht->persistent);