cvs: ZendEngine2(PHP_5_3) / zend_exceptions.c zend_exceptions.h zend_objects.c /tests exception_007.phpt exception_008.phpt gc_030.phpt

From: Date: Sun, 13 Jul 2008 21:42:49 +0000
Subject: cvs: ZendEngine2(PHP_5_3) / zend_exceptions.c zend_exceptions.h zend_objects.c /tests exception_007.phpt exception_008.phpt gc_030.phpt
Groups: php.doc php.zend-engine.cvs 
Request: Send a blank email to phpdoc+get-969379090@lists.php.net to get a copy of this message
helly Sun Jul 13 21:42:49 2008 UTC Added files: (Branch: PHP_5_3) /ZendEngine2/tests exception_007.phpt exception_008.phpt Modified files: /ZendEngine2 zend_exceptions.c zend_exceptions.h zend_objects.c /ZendEngine2/tests gc_030.phpt Log: - MFH Exception handling [DOC] - Exceptions can be thrown while exceptions are pending, they are linked - Exceptions can be handled in __destruct - Add optional Exception $previous parameter to . Exception::__construct . ErrorException::__construct

http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_exceptions.c?r1=1.79.2.6.2.9.2.10&r2=1.79.2.6.2.9.2.11&diff_format=u Index: ZendEngine2/zend_exceptions.c diff -u ZendEngine2/zend_exceptions.c:1.79.2.6.2.9.2.10 ZendEngine2/zend_exceptions.c:1.79.2.6.2.9.2.11 --- ZendEngine2/zend_exceptions.c:1.79.2.6.2.9.2.10 Sun Jul 13 09:32:46 2008 +++ ZendEngine2/zend_exceptions.c Sun Jul 13 21:42:49 2008 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_exceptions.c,v 1.79.2.6.2.9.2.10 2008/07/13 09:32:46 tony2001 Exp $ */ +/* $Id: zend_exceptions.c,v 1.79.2.6.2.9.2.11 2008/07/13 21:42:49 helly Exp $ */ #include "zend.h" #include "zend_API.h" @@ -33,13 +33,37 @@ static zend_object_handlers default_exception_handlers; ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC); +void zend_exception_set_previous(zval *add_previous TSRMLS_DC) +{ + zval *exception = EG(exception), *previous; + + if (exception == add_previous || !add_previous) { + return; + } + if (Z_TYPE_P(add_previous) != IS_OBJECT && !instanceof_function(Z_OBJCE_P(add_previous), default_exception_ce TSRMLS_CC)) { + zend_error(E_ERROR, "Cannot set non exception as previous exception"); + return; + } + if (!exception) { + EG(exception) = add_previous; + return; + } + while (exception && exception != add_previous && Z_OBJ_HANDLE_P(exception) != Z_OBJ_HANDLE_P(add_previous)) { + previous = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 1 TSRMLS_CC); + if (Z_TYPE_P(previous) == IS_NULL) { + zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, add_previous TSRMLS_CC); + return; + } + exception = previous; + } +} + void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */ { if (exception != NULL) { - if (EG(exception)) { - zend_update_property(default_exception_ce, exception, "previous", sizeof("previous")-1, EG(exception) TSRMLS_CC); - } + zval *previous = EG(exception); EG(exception) = exception; + zend_exception_set_previous(previous TSRMLS_CC); } if (!EG(current_execute_data)) { zend_error(E_ERROR, "Exception thrown without a stack frame"); @@ -129,8 +153,8 @@ zval *object, *previous = NULL; int argc = ZEND_NUM_ARGS(), message_len; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|slO", &message, &message_len, &code, &previous, default_exception_ce) == FAILURE) { - zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code ]])"); + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|slO!", &message, &message_len, &code, &previous, default_exception_ce) == FAILURE) { + zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]])"); } object = getThis(); @@ -158,8 +182,8 @@ zval *object, *previous = NULL; int argc = ZEND_NUM_ARGS(), message_len, filename_len; - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|sllslO", &message, &message_len, &code, &severity, &filename, &filename_len, &lineno, &previous, default_exception_ce) == FAILURE) { - zend_error(E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno ]]]]])"); + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|sllslO!", &message, &message_len, &code, &severity, &filename, &filename_len, &lineno, &previous, default_exception_ce) == FAILURE) { + zend_error(E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno [, Exception $previous = NULL]]]]]])"); } object = getThis(); http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_exceptions.h?r1=1.21.2.1.2.2.2.1&r2=1.21.2.1.2.2.2.2&diff_format=u Index: ZendEngine2/zend_exceptions.h diff -u ZendEngine2/zend_exceptions.h:1.21.2.1.2.2.2.1 ZendEngine2/zend_exceptions.h:1.21.2.1.2.2.2.2 --- ZendEngine2/zend_exceptions.h:1.21.2.1.2.2.2.1 Mon Dec 31 07:17:04 2007 +++ ZendEngine2/zend_exceptions.h Sun Jul 13 21:42:49 2008 @@ -19,13 +19,15 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_exceptions.h,v 1.21.2.1.2.2.2.1 2007/12/31 07:17:04 sebastian Exp $ */ +/* $Id: zend_exceptions.h,v 1.21.2.1.2.2.2.2 2008/07/13 21:42:49 helly Exp $ */ #ifndef ZEND_EXCEPTIONS_H #define ZEND_EXCEPTIONS_H BEGIN_EXTERN_C() +ZEND_API void zend_exception_set_previous(zval *add_previous TSRMLS_DC); + void zend_throw_exception_internal(zval *exception TSRMLS_DC); void zend_register_default_exception(TSRMLS_D); http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_objects.c?r1=1.56.2.3.2.6.2.3&r2=1.56.2.3.2.6.2.4&diff_format=u Index: ZendEngine2/zend_objects.c diff -u ZendEngine2/zend_objects.c:1.56.2.3.2.6.2.3 ZendEngine2/zend_objects.c:1.56.2.3.2.6.2.4 --- ZendEngine2/zend_objects.c:1.56.2.3.2.6.2.3 Tue Mar 18 14:10:43 2008 +++ ZendEngine2/zend_objects.c Sun Jul 13 21:42:49 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_objects.c,v 1.56.2.3.2.6.2.3 2008/03/18 14:10:43 felipe Exp $ */ +/* $Id: zend_objects.c,v 1.56.2.3.2.6.2.4 2008/07/13 21:42:49 helly Exp $ */ #include "zend.h" #include "zend_globals.h" @@ -99,20 +99,7 @@ old_exception = EG(exception); EG(exception) = NULL; zend_call_method_with_0_params(&obj, object->ce, &destructor, ZEND_DESTRUCTOR_FUNC_NAME, NULL); - if (old_exception) { - if (EG(exception)) { - zend_class_entry *default_exception_ce = zend_exception_get_default(TSRMLS_C); - zval *file = zend_read_property(default_exception_ce, old_exception, "file", sizeof("file")-1, 1 TSRMLS_CC); - zval *line = zend_read_property(default_exception_ce, old_exception, "line", sizeof("line")-1, 1 TSRMLS_CC); - - zval_ptr_dtor(&obj); - zval_ptr_dtor(&EG(exception)); - EG(exception) = old_exception; - zend_error(E_ERROR, "Ignoring exception from %s::__destruct() while an exception is already active (Uncaught %s in %s on line %ld)", - object->ce->name, Z_OBJCE_P(old_exception)->name, Z_STRVAL_P(file), Z_LVAL_P(line)); - } - EG(exception) = old_exception; - } + zend_exception_set_previous(old_exception TSRMLS_CC); zval_ptr_dtor(&obj); } } http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/gc_030.phpt?r1=1.1.2.1&r2=1.1.2.2&diff_format=u Index: ZendEngine2/tests/gc_030.phpt diff -u ZendEngine2/tests/gc_030.phpt:1.1.2.1 ZendEngine2/tests/gc_030.phpt:1.1.2.2 --- ZendEngine2/tests/gc_030.phpt:1.1.2.1 Tue Jul 8 08:16:09 2008 +++ ZendEngine2/tests/gc_030.phpt Sun Jul 13 21:42:49 2008 @@ -18,4 +18,14 @@ gc_collect_cycles(); ?> --EXPECTF-- -Fatal error: Ignoring exception from foo::__destruct() while an exception is already active (Uncaught Exception in %sgc_030.php on line %d) in %sgc_030.php on line %d +Fatal error: Uncaught exception 'Exception' with message 'foobar' in %sgc_030.php:%d +Stack trace: +#0 [internal function]: foo->__destruct() +#1 %sgc_030.php(%d): gc_collect_cycles() +#2 {main} + +Next exception 'Exception' with message 'foobar' in %sgc_030.php:%d +Stack trace: +#0 %sgc_030.php(%d): foo->__destruct() +#1 {main} + thrown in %sgc_030.php on line %d \ No newline at end of file http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/exception_007.phpt?view=markup&rev=1.1 Index: ZendEngine2/tests/exception_007.phpt +++ ZendEngine2/tests/exception_007.phpt --TEST-- Setting previous exception --FILE-- <?php try { try { throw new Exception("First", 1, new Exception("Another", 0, NULL)); } catch (Exception $e) { throw new Exception("Second", 2, $e); } } catch (Exception $e) { throw new Exception("Third", 3, $e); } ?> ===DONE=== --EXPECTF-- Fatal error: Uncaught exception 'Exception' with message 'Another' in %sexception_007.php:%d Stack trace: #0 {main} Next exception 'Exception' with message 'First' in %sexception_007.php:%d Stack trace: #0 {main} Next exception 'Exception' with message 'Second' in %sexception_007.php:%d Stack trace: #0 {main} Next exception 'Exception' with message 'Third' in %sexception_007.php:%d Stack trace: #0 {main} thrown in %sexception_007.php on line %d http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/exception_008.phpt?view=markup&rev=1.1 Index: ZendEngine2/tests/exception_008.phpt +++ ZendEngine2/tests/exception_008.phpt --TEST-- Exception in __destruct while exception is pending --FILE-- <?php class TestFirst { function __destruct() { throw new Exception("First"); } } class TestSecond { function __destruct() { throw new Exception("Second"); } } $ar = array(new TestFirst, new TestSecond); unset($ar); ?> ===DONE=== --EXPECTF-- Fatal error: Uncaught exception 'Exception' with message 'First' in %sexception_008.php:%d Stack trace: #0 %sexception_008.php(%d): TestFirst->__destruct() #1 {main} Next exception 'Exception' with message 'Second' in %sexception_008.php:%d Stack trace: #0 %sexception_008.php(%d): TestSecond->__destruct() #1 {main} thrown in %sexception_008.php on line %d
« previous php.doc (#969379090) next »