cvs: ZendEngine2 / zend.c zend_builtin_functions.c zend_execute_API.c zend_globals.h php4/tests/lang 035.phpt
| From: | Stig Bakken | Date: | Fri, 16 Aug 2002 00:41:36 +0000 |
| Subject: | cvs: ZendEngine2 / zend.c zend_builtin_functions.c zend_execute_API.c zend_globals.h php4/tests/lang 035.phpt | ||
| Groups: | php.zend-engine.cvs | ||
| Request: | Send a blank email to php-zend-engine-cvs+get-316@lists.php.net to get a copy of this message | ||
ssb Thu Aug 15 20:41:36 2002 EDT
Modified files:
/php4/tests/lang 035.phpt
/ZendEngine2 zend.c zend_builtin_functions.c zend_execute_API.c
zend_globals.h
Log:
@- Added set_exception_handler() function for registering a global,
@ catch-all exception handling function (Stig)
- Added set_exception_handler() function for registering a global,
catch-all exception handling function (Stig)
Index: php4/tests/lang/035.phpt diff -u php4/tests/lang/035.phpt:1.1 php4/tests/lang/035.phpt:1.2 --- php4/tests/lang/035.phpt:1.1 Wed Jul 17 04:49:26 2002 +++ php4/tests/lang/035.phpt Thu Aug 15 20:41:35 2002 @@ -1,7 +1,21 @@ +--TEST-- +ZE2: set_exception_handler() +--SKIPIF-- +<?php if (version_compare(zend_version(), "2", "<")) print "skip"; ?> +--FILE-- +<?php ----- EXPECTED OUTPUT -test_i -test ----- ACTUAL OUTPUT -test_itest ----- FAILED +set_exception_handler("my_handler"); +try { + throw new exception(); +} catch (stdClass $e) { + print "BAR\n"; +} + +function my_handler($exception) { + print "FOO\n"; +} + +?> +--EXPECT-- +FOO Index: ZendEngine2/zend.c diff -u ZendEngine2/zend.c:1.170 ZendEngine2/zend.c:1.171 --- ZendEngine2/zend.c:1.170 Wed Aug 14 20:25:27 2002 +++ ZendEngine2/zend.c Thu Aug 15 20:41:35 2002 @@ -45,6 +45,7 @@ /* true multithread-shared globals */ ZEND_API zend_class_entry *zend_standard_class_def = NULL; +ZEND_API zend_class_entry *zend_exception_class_def = NULL; ZEND_API int (*zend_printf)(const char *format, ...); ZEND_API zend_write_func_t zend_write; ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path); @@ -271,6 +272,33 @@ } +static void register_exception_class(void) +{ + zend_exception_class_def = malloc(sizeof(zend_class_entry)); + + zend_exception_class_def->type = ZEND_INTERNAL_CLASS; + zend_exception_class_def->name_length = sizeof("Exception") - 1; + zend_exception_class_def->name = zend_strndup("Exception", zend_exception_class_def->name_length); + zend_exception_class_def->parent = NULL; + zend_hash_init_ex(&zend_exception_class_def->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->private_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->protected_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_exception_class_def->static_members = (HashTable *) malloc(sizeof(HashTable)); + zend_hash_init_ex(zend_exception_class_def->static_members, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->constants_table, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1, 0); + zend_exception_class_def->constructor = NULL; + zend_exception_class_def->destructor = NULL; + zend_exception_class_def->clone = NULL; + zend_exception_class_def->handle_function_call = NULL; + zend_exception_class_def->handle_property_get = NULL; + zend_exception_class_def->handle_property_set = NULL; + zend_exception_class_def->refcount = 1; + zend_hash_add(GLOBAL_CLASS_TABLE, "exception", sizeof("exception"), &zend_exception_class_def, sizeof(zend_class_entry *), NULL); +} + + static void zend_set_default_compile_time_values(TSRMLS_D) { /* default compile-time values */ @@ -331,6 +359,7 @@ zend_init_rsrc_plist(TSRMLS_C); EG(lambda_count)=0; EG(user_error_handler) = NULL; + EG(user_exception_handler) = NULL; EG(in_execution) = 0; } @@ -443,9 +472,11 @@ zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, NULL, 1, 0); register_standard_class(); + register_exception_class(); zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0); zend_init_rsrc_list_dtors(); + /* This zval can be used to initialize allocate zval's to an uninit'ed value */ zval_used_for_init.is_ref = 0; zval_used_for_init.refcount = 1; @@ -471,6 +502,7 @@ zend_startup_constants(); zend_set_default_compile_time_values(TSRMLS_C); EG(user_error_handler) = NULL; + EG(user_exception_handler) = NULL; #endif zend_register_standard_constants(TSRMLS_C); @@ -828,8 +860,32 @@ EG(return_value_ptr_ptr) = retval ? retval : &local_retval; zend_execute(EG(active_op_array) TSRMLS_CC); if (EG(exception)) { +#if 1 /* support set_exception_handler() */ + if (EG(user_exception_handler)) { + zval *orig_user_exception_handler; + zval ***params, *retval2; + params = (zval ***)emalloc(sizeof(zval **)); + params[0] = &EG(exception); + orig_user_exception_handler = EG(user_exception_handler); + if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) { + zval_ptr_dtor(&retval2); + } + efree(params); + zval_ptr_dtor(&EG(exception)); + EG(exception) = NULL; + } else { + zval_ptr_dtor(&EG(exception)); + EG(exception) = NULL; + zend_error(E_ERROR, "Uncaught exception!"); + } + if (!retval) { + zval_ptr_dtor(EG(return_value_ptr_ptr)); + local_retval = NULL; + } +#else zval_ptr_dtor(&EG(exception)); zend_error(E_ERROR, "Uncaught exception!"); +#endif } else if (!retval) { zval_ptr_dtor(EG(return_value_ptr_ptr)); local_retval = NULL; Index: ZendEngine2/zend_builtin_functions.c diff -u ZendEngine2/zend_builtin_functions.c:1.130 ZendEngine2/zend_builtin_functions.c:1.131 --- ZendEngine2/zend_builtin_functions.c:1.130 Fri Jul 26 06:38:24 2002 +++ ZendEngine2/zend_builtin_functions.c Thu Aug 15 20:41:35 2002 @@ -56,6 +56,8 @@ static ZEND_FUNCTION(trigger_error); static ZEND_FUNCTION(set_error_handler); static ZEND_FUNCTION(restore_error_handler); +static ZEND_FUNCTION(set_exception_handler); +static ZEND_FUNCTION(restore_exception_handler); static ZEND_FUNCTION(get_declared_classes); static ZEND_FUNCTION(get_defined_functions); static ZEND_FUNCTION(get_defined_vars); @@ -108,6 +110,8 @@ ZEND_FALIAS(user_error, trigger_error, NULL) ZEND_FE(set_error_handler, NULL) ZEND_FE(restore_error_handler, NULL) + ZEND_FE(set_exception_handler, NULL) + ZEND_FE(restore_exception_handler, NULL) ZEND_FE(get_declared_classes, NULL) ZEND_FE(get_defined_functions, NULL) ZEND_FE(get_defined_vars, NULL) @@ -958,6 +962,59 @@ /* }}} */ +/* {{{ proto string set_exception_handler(string exception_handler) + Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */ +ZEND_FUNCTION(set_exception_handler) +{ + zval **exception_handler; + zend_bool had_orig_exception_handler=0; + + if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &exception_handler)==FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + convert_to_string_ex(exception_handler); + if (EG(user_exception_handler)) { + had_orig_exception_handler = 1; + *return_value = *EG(user_exception_handler); + zval_copy_ctor(return_value); + zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler)); + } + ALLOC_ZVAL(EG(user_exception_handler)); + + if (Z_STRLEN_PP(exception_handler)==0) { /* unset user-defined handler */ + FREE_ZVAL(EG(user_exception_handler)); + EG(user_exception_handler) = NULL; + RETURN_TRUE; + } + + *EG(user_exception_handler) = **exception_handler; + zval_copy_ctor(EG(user_exception_handler)); + + if (!had_orig_exception_handler) { + RETURN_NULL(); + } +} +/* }}} */ + + +/* {{{ proto void restore_exception_handler(void) + Restores the previously defined exception handler function */ +ZEND_FUNCTION(restore_exception_handler) +{ + if (EG(user_exception_handler)) { + zval_ptr_dtor(&EG(user_exception_handler)); + } + if (zend_ptr_stack_num_elements(&EG(user_exception_handlers))==0) { + EG(user_exception_handler) = NULL; + } else { + EG(user_exception_handler) = zend_ptr_stack_pop(&EG(user_exception_handlers)); + } + RETURN_TRUE; +} +/* }}} */ + + static int copy_class_name(zend_class_entry **pce, int num_args, va_list args, zend_hash_key *hash_key) { zval *array = va_arg(args, zval *); @@ -1199,7 +1256,6 @@ char *function_name; char *filename; char *class_name; - zend_uint class_name_length; zval *stack_frame; ptr = EG(current_execute_data); @@ -1217,7 +1273,6 @@ if (ptr->object) { class_name = Z_OBJCE(*ptr->object)->name; - class_name_length = Z_OBJCE(*ptr->object)->name_length; } if (ptr->function_state.function->common.scope) { class_name = ptr->function_state.function->common.scope->name; @@ -1294,3 +1349,11 @@ } } /* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + */ Index: ZendEngine2/zend_execute_API.c diff -u ZendEngine2/zend_execute_API.c:1.169 ZendEngine2/zend_execute_API.c:1.170 --- ZendEngine2/zend_execute_API.c:1.169 Tue Aug 13 12:46:40 2002 +++ ZendEngine2/zend_execute_API.c Thu Aug 15 20:41:36 2002 @@ -158,6 +158,7 @@ EG(user_error_handler) = NULL; zend_ptr_stack_init(&EG(user_error_handlers)); + zend_ptr_stack_init(&EG(user_exception_handlers)); EG(orig_error_reporting) = EG(error_reporting); zend_objects_store_init(&EG(objects_store), 1024); @@ -232,8 +233,16 @@ FREE_ZVAL(EG(user_error_handler)); } + if (EG(user_exception_handler)) { + zval_dtor(EG(user_exception_handler)); + FREE_ZVAL(EG(user_exception_handler)); + } + zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1); zend_ptr_stack_destroy(&EG(user_error_handlers)); + + zend_ptr_stack_clean(&EG(user_exception_handlers), ZVAL_DESTRUCTOR, 1); + zend_ptr_stack_destroy(&EG(user_exception_handlers)); EG(error_reporting) = EG(orig_error_reporting); zend_objects_store_destroy(&EG(objects_store)); Index: ZendEngine2/zend_globals.h diff -u ZendEngine2/zend_globals.h:1.104 ZendEngine2/zend_globals.h:1.105 --- ZendEngine2/zend_globals.h:1.104 Wed Aug 14 20:25:27 2002 +++ ZendEngine2/zend_globals.h Thu Aug 15 20:41:36 2002 @@ -193,7 +193,9 @@ int garbage_ptr; zval *user_error_handler; + zval *user_exception_handler; zend_ptr_stack user_error_handlers; + zend_ptr_stack user_exception_handlers; /* timeout support */ int timeout_seconds;
Index: php4/tests/lang/035.phpt diff -u php4/tests/lang/035.phpt:1.1 php4/tests/lang/035.phpt:1.2 --- php4/tests/lang/035.phpt:1.1 Wed Jul 17 04:49:26 2002 +++ php4/tests/lang/035.phpt Thu Aug 15 20:41:35 2002 @@ -1,7 +1,21 @@ +--TEST-- +ZE2: set_exception_handler() +--SKIPIF-- +<?php if (version_compare(zend_version(), "2", "<")) print "skip"; ?> +--FILE-- +<?php ----- EXPECTED OUTPUT -test_i -test ----- ACTUAL OUTPUT -test_itest ----- FAILED +set_exception_handler("my_handler"); +try { + throw new exception(); +} catch (stdClass $e) { + print "BAR\n"; +} + +function my_handler($exception) { + print "FOO\n"; +} + +?> +--EXPECT-- +FOO Index: ZendEngine2/zend.c diff -u ZendEngine2/zend.c:1.170 ZendEngine2/zend.c:1.171 --- ZendEngine2/zend.c:1.170 Wed Aug 14 20:25:27 2002 +++ ZendEngine2/zend.c Thu Aug 15 20:41:35 2002 @@ -45,6 +45,7 @@ /* true multithread-shared globals */ ZEND_API zend_class_entry *zend_standard_class_def = NULL; +ZEND_API zend_class_entry *zend_exception_class_def = NULL; ZEND_API int (*zend_printf)(const char *format, ...); ZEND_API zend_write_func_t zend_write; ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path); @@ -271,6 +272,33 @@ } +static void register_exception_class(void) +{ + zend_exception_class_def = malloc(sizeof(zend_class_entry)); + + zend_exception_class_def->type = ZEND_INTERNAL_CLASS; + zend_exception_class_def->name_length = sizeof("Exception") - 1; + zend_exception_class_def->name = zend_strndup("Exception", zend_exception_class_def->name_length); + zend_exception_class_def->parent = NULL; + zend_hash_init_ex(&zend_exception_class_def->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->private_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->protected_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_exception_class_def->static_members = (HashTable *) malloc(sizeof(HashTable)); + zend_hash_init_ex(zend_exception_class_def->static_members, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->constants_table, 0, NULL, ZVAL_PTR_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0); + zend_hash_init_ex(&zend_exception_class_def->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1, 0); + zend_exception_class_def->constructor = NULL; + zend_exception_class_def->destructor = NULL; + zend_exception_class_def->clone = NULL; + zend_exception_class_def->handle_function_call = NULL; + zend_exception_class_def->handle_property_get = NULL; + zend_exception_class_def->handle_property_set = NULL; + zend_exception_class_def->refcount = 1; + zend_hash_add(GLOBAL_CLASS_TABLE, "exception", sizeof("exception"), &zend_exception_class_def, sizeof(zend_class_entry *), NULL); +} + + static void zend_set_default_compile_time_values(TSRMLS_D) { /* default compile-time values */ @@ -331,6 +359,7 @@ zend_init_rsrc_plist(TSRMLS_C); EG(lambda_count)=0; EG(user_error_handler) = NULL; + EG(user_exception_handler) = NULL; EG(in_execution) = 0; } @@ -443,9 +472,11 @@ zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, NULL, 1, 0); register_standard_class(); + register_exception_class(); zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0); zend_init_rsrc_list_dtors(); + /* This zval can be used to initialize allocate zval's to an uninit'ed value */ zval_used_for_init.is_ref = 0; zval_used_for_init.refcount = 1; @@ -471,6 +502,7 @@ zend_startup_constants(); zend_set_default_compile_time_values(TSRMLS_C); EG(user_error_handler) = NULL; + EG(user_exception_handler) = NULL; #endif zend_register_standard_constants(TSRMLS_C); @@ -828,8 +860,32 @@ EG(return_value_ptr_ptr) = retval ? retval : &local_retval; zend_execute(EG(active_op_array) TSRMLS_CC); if (EG(exception)) { +#if 1 /* support set_exception_handler() */ + if (EG(user_exception_handler)) { + zval *orig_user_exception_handler; + zval ***params, *retval2; + params = (zval ***)emalloc(sizeof(zval **)); + params[0] = &EG(exception); + orig_user_exception_handler = EG(user_exception_handler); + if (call_user_function_ex(CG(function_table), NULL, orig_user_exception_handler, &retval2, 1, params, 1, NULL TSRMLS_CC) == SUCCESS) { + zval_ptr_dtor(&retval2); + } + efree(params); + zval_ptr_dtor(&EG(exception)); + EG(exception) = NULL; + } else { + zval_ptr_dtor(&EG(exception)); + EG(exception) = NULL; + zend_error(E_ERROR, "Uncaught exception!"); + } + if (!retval) { + zval_ptr_dtor(EG(return_value_ptr_ptr)); + local_retval = NULL; + } +#else zval_ptr_dtor(&EG(exception)); zend_error(E_ERROR, "Uncaught exception!"); +#endif } else if (!retval) { zval_ptr_dtor(EG(return_value_ptr_ptr)); local_retval = NULL; Index: ZendEngine2/zend_builtin_functions.c diff -u ZendEngine2/zend_builtin_functions.c:1.130 ZendEngine2/zend_builtin_functions.c:1.131 --- ZendEngine2/zend_builtin_functions.c:1.130 Fri Jul 26 06:38:24 2002 +++ ZendEngine2/zend_builtin_functions.c Thu Aug 15 20:41:35 2002 @@ -56,6 +56,8 @@ static ZEND_FUNCTION(trigger_error); static ZEND_FUNCTION(set_error_handler); static ZEND_FUNCTION(restore_error_handler); +static ZEND_FUNCTION(set_exception_handler); +static ZEND_FUNCTION(restore_exception_handler); static ZEND_FUNCTION(get_declared_classes); static ZEND_FUNCTION(get_defined_functions); static ZEND_FUNCTION(get_defined_vars); @@ -108,6 +110,8 @@ ZEND_FALIAS(user_error, trigger_error, NULL) ZEND_FE(set_error_handler, NULL) ZEND_FE(restore_error_handler, NULL) + ZEND_FE(set_exception_handler, NULL) + ZEND_FE(restore_exception_handler, NULL) ZEND_FE(get_declared_classes, NULL) ZEND_FE(get_defined_functions, NULL) ZEND_FE(get_defined_vars, NULL) @@ -958,6 +962,59 @@ /* }}} */ +/* {{{ proto string set_exception_handler(string exception_handler) + Sets a user-defined exception handler function. Returns the previously defined exception handler, or false on error */ +ZEND_FUNCTION(set_exception_handler) +{ + zval **exception_handler; + zend_bool had_orig_exception_handler=0; + + if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &exception_handler)==FAILURE) { + ZEND_WRONG_PARAM_COUNT(); + } + + convert_to_string_ex(exception_handler); + if (EG(user_exception_handler)) { + had_orig_exception_handler = 1; + *return_value = *EG(user_exception_handler); + zval_copy_ctor(return_value); + zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler)); + } + ALLOC_ZVAL(EG(user_exception_handler)); + + if (Z_STRLEN_PP(exception_handler)==0) { /* unset user-defined handler */ + FREE_ZVAL(EG(user_exception_handler)); + EG(user_exception_handler) = NULL; + RETURN_TRUE; + } + + *EG(user_exception_handler) = **exception_handler; + zval_copy_ctor(EG(user_exception_handler)); + + if (!had_orig_exception_handler) { + RETURN_NULL(); + } +} +/* }}} */ + + +/* {{{ proto void restore_exception_handler(void) + Restores the previously defined exception handler function */ +ZEND_FUNCTION(restore_exception_handler) +{ + if (EG(user_exception_handler)) { + zval_ptr_dtor(&EG(user_exception_handler)); + } + if (zend_ptr_stack_num_elements(&EG(user_exception_handlers))==0) { + EG(user_exception_handler) = NULL; + } else { + EG(user_exception_handler) = zend_ptr_stack_pop(&EG(user_exception_handlers)); + } + RETURN_TRUE; +} +/* }}} */ + + static int copy_class_name(zend_class_entry **pce, int num_args, va_list args, zend_hash_key *hash_key) { zval *array = va_arg(args, zval *); @@ -1199,7 +1256,6 @@ char *function_name; char *filename; char *class_name; - zend_uint class_name_length; zval *stack_frame; ptr = EG(current_execute_data); @@ -1217,7 +1273,6 @@ if (ptr->object) { class_name = Z_OBJCE(*ptr->object)->name; - class_name_length = Z_OBJCE(*ptr->object)->name_length; } if (ptr->function_state.function->common.scope) { class_name = ptr->function_state.function->common.scope->name; @@ -1294,3 +1349,11 @@ } } /* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: t + * End: + */ Index: ZendEngine2/zend_execute_API.c diff -u ZendEngine2/zend_execute_API.c:1.169 ZendEngine2/zend_execute_API.c:1.170 --- ZendEngine2/zend_execute_API.c:1.169 Tue Aug 13 12:46:40 2002 +++ ZendEngine2/zend_execute_API.c Thu Aug 15 20:41:36 2002 @@ -158,6 +158,7 @@ EG(user_error_handler) = NULL; zend_ptr_stack_init(&EG(user_error_handlers)); + zend_ptr_stack_init(&EG(user_exception_handlers)); EG(orig_error_reporting) = EG(error_reporting); zend_objects_store_init(&EG(objects_store), 1024); @@ -232,8 +233,16 @@ FREE_ZVAL(EG(user_error_handler)); } + if (EG(user_exception_handler)) { + zval_dtor(EG(user_exception_handler)); + FREE_ZVAL(EG(user_exception_handler)); + } + zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1); zend_ptr_stack_destroy(&EG(user_error_handlers)); + + zend_ptr_stack_clean(&EG(user_exception_handlers), ZVAL_DESTRUCTOR, 1); + zend_ptr_stack_destroy(&EG(user_exception_handlers)); EG(error_reporting) = EG(orig_error_reporting); zend_objects_store_destroy(&EG(objects_store)); Index: ZendEngine2/zend_globals.h diff -u ZendEngine2/zend_globals.h:1.104 ZendEngine2/zend_globals.h:1.105 --- ZendEngine2/zend_globals.h:1.104 Wed Aug 14 20:25:27 2002 +++ ZendEngine2/zend_globals.h Thu Aug 15 20:41:36 2002 @@ -193,7 +193,9 @@ int garbage_ptr; zval *user_error_handler; + zval *user_exception_handler; zend_ptr_stack user_error_handlers; + zend_ptr_stack user_exception_handlers; /* timeout support */ int timeout_seconds;