PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - Zend - zend_exceptions.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 334 409 81.7 %
Date: 2014-09-19 Functions: 31 34 91.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Marcus Boerger <helly@php.net>                              |
      17             :    |          Sterling Hughes <sterling@php.net>                          |
      18             :    |          Zeev Suraski <zeev@zend.com>                                |
      19             :    +----------------------------------------------------------------------+
      20             : */
      21             : 
      22             : /* $Id$ */
      23             : 
      24             : #include "zend.h"
      25             : #include "zend_API.h"
      26             : #include "zend_builtin_functions.h"
      27             : #include "zend_interfaces.h"
      28             : #include "zend_exceptions.h"
      29             : #include "zend_vm.h"
      30             : #include "zend_dtrace.h"
      31             : 
      32             : static zend_class_entry *default_exception_ce;
      33             : static zend_class_entry *error_exception_ce;
      34             : static zend_object_handlers default_exception_handlers;
      35             : ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
      36             : 
      37        1264 : void zend_exception_set_previous(zend_object *exception, zend_object *add_previous TSRMLS_DC)
      38             : {
      39             :     zval tmp, *previous, zv, *pzv;
      40             : 
      41        1264 :         if (exception == add_previous || !add_previous || !exception) {
      42        1256 :                 return;
      43             :         }
      44           8 :         ZVAL_OBJ(&tmp, add_previous);
      45           8 :         if (!instanceof_function(Z_OBJCE(tmp), default_exception_ce TSRMLS_CC)) {
      46           0 :                 zend_error(E_ERROR, "Cannot set non exception as previous exception");
      47           0 :                 return;
      48             :         }
      49           8 :         ZVAL_OBJ(&zv, exception);
      50           8 :         pzv = &zv;
      51             :         do {
      52           8 :                 previous = zend_read_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, 1 TSRMLS_CC);
      53           8 :                 if (Z_TYPE_P(previous) == IS_NULL) {
      54           8 :                         zend_update_property(default_exception_ce, pzv, "previous", sizeof("previous")-1, &tmp TSRMLS_CC);
      55           8 :                         GC_REFCOUNT(add_previous)--;
      56           8 :                         return;
      57             :                 }
      58           0 :                 pzv = previous;
      59           0 :         } while (pzv && Z_OBJ_P(pzv) != add_previous);
      60             : }
      61             : 
      62         584 : void zend_exception_save(TSRMLS_D) /* {{{ */
      63             : {
      64         584 :         if (EG(prev_exception)) {
      65           4 :                 zend_exception_set_previous(EG(exception), EG(prev_exception) TSRMLS_CC);
      66             :         }
      67         584 :         if (EG(exception)) {
      68          15 :                 EG(prev_exception) = EG(exception);
      69             :         }
      70         584 :         EG(exception) = NULL;
      71         584 : }
      72             : /* }}} */
      73             : 
      74       20143 : void zend_exception_restore(TSRMLS_D) /* {{{ */
      75             : {
      76       20143 :         if (EG(prev_exception)) {
      77          15 :                 if (EG(exception)) {
      78           3 :                         zend_exception_set_previous(EG(exception), EG(prev_exception) TSRMLS_CC);
      79             :                 } else {
      80          12 :                         EG(exception) = EG(prev_exception);
      81             :                 }
      82          15 :                 EG(prev_exception) = NULL;
      83             :         }
      84       20143 : }
      85             : /* }}} */
      86             : 
      87        2701 : void zend_throw_exception_internal(zval *exception TSRMLS_DC) /* {{{ */
      88             : {
      89             : #ifdef HAVE_DTRACE
      90             :         if (DTRACE_EXCEPTION_THROWN_ENABLED()) {
      91             :                 zend_string *classname;
      92             : 
      93             :                 if (exception != NULL) {
      94             :                         classname = zend_get_object_classname(Z_OBJ_P(exception) TSRMLS_CC);
      95             :                         DTRACE_EXCEPTION_THROWN(classname->val);
      96             :                 } else {
      97             :                         DTRACE_EXCEPTION_THROWN(NULL);
      98             :                 }
      99             :         }
     100             : #endif /* HAVE_DTRACE */
     101             : 
     102        2701 :         if (exception != NULL) {
     103        1252 :                 zend_object *previous = EG(exception);
     104        1252 :                 zend_exception_set_previous(Z_OBJ_P(exception), EG(exception) TSRMLS_CC);
     105        1252 :                 EG(exception) = Z_OBJ_P(exception);
     106        1252 :                 if (previous) {
     107           0 :                         return;
     108             :                 }
     109             :         }
     110        2701 :         if (!EG(current_execute_data)) {
     111           3 :                 if(EG(exception)) {
     112           3 :                         zend_exception_error(EG(exception), E_ERROR TSRMLS_CC);
     113             :                 }
     114           0 :                 zend_error(E_ERROR, "Exception thrown without a stack frame");
     115             :         }
     116             : 
     117        2698 :         if (zend_throw_exception_hook) {
     118           0 :                 zend_throw_exception_hook(exception TSRMLS_CC);
     119             :         }
     120             : 
     121        7020 :         if (!EG(current_execute_data)->func ||
     122        2693 :             !ZEND_USER_CODE(EG(current_execute_data)->func->common.type) ||
     123        1629 :             (EG(current_execute_data)->opline+1)->opcode == ZEND_HANDLE_EXCEPTION) {
     124             :                 /* no need to rethrow the exception */
     125        1090 :                 return;
     126             :         }
     127        1608 :         EG(opline_before_exception) = EG(current_execute_data)->opline;
     128        1608 :         EG(current_execute_data)->opline = EG(exception_op);
     129             : }
     130             : /* }}} */
     131             : 
     132         101 : ZEND_API void zend_clear_exception(TSRMLS_D) /* {{{ */
     133             : {
     134         101 :         if (EG(prev_exception)) {
     135             :                                 
     136           0 :                 OBJ_RELEASE(EG(prev_exception));
     137           0 :                 EG(prev_exception) = NULL;
     138             :         }
     139         101 :         if (!EG(exception)) {
     140          91 :                 return;
     141             :         }
     142          10 :         OBJ_RELEASE(EG(exception));
     143          10 :         EG(exception) = NULL;
     144          10 :         EG(current_execute_data)->opline = EG(opline_before_exception);
     145             : #if ZEND_DEBUG
     146             :         EG(opline_before_exception) = NULL;
     147             : #endif
     148             : }
     149             : /* }}} */
     150             : 
     151        1668 : static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, int skip_top_traces TSRMLS_DC) /* {{{ */
     152             : {
     153             :         zval obj;
     154             :         zend_object *object;
     155             :         zval trace;
     156             : 
     157        1668 :         Z_OBJ(obj) = object = zend_objects_new(class_type TSRMLS_CC);
     158        1668 :         Z_OBJ_HT(obj) = &default_exception_handlers;
     159             : 
     160        1668 :         object_properties_init(object, class_type);
     161             : 
     162        1668 :         zend_fetch_debug_backtrace(&trace, skip_top_traces, 0, 0 TSRMLS_CC);
     163             :         Z_SET_REFCOUNT(trace, 0);
     164             : 
     165        1668 :         zend_update_property_string(default_exception_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename(TSRMLS_C) TSRMLS_CC);
     166        1668 :         zend_update_property_long(default_exception_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
     167        1668 :         zend_update_property(default_exception_ce, &obj, "trace", sizeof("trace")-1, &trace TSRMLS_CC);
     168             : 
     169        1668 :         return object;
     170             : }
     171             : /* }}} */
     172             : 
     173        1666 : static zend_object *zend_default_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
     174             : {
     175        1666 :         return zend_default_exception_new_ex(class_type, 0 TSRMLS_CC);
     176             : }
     177             : /* }}} */
     178             : 
     179           2 : static zend_object *zend_error_exception_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
     180             : {
     181           2 :         return zend_default_exception_new_ex(class_type, 2 TSRMLS_CC);
     182             : }
     183             : /* }}} */
     184             : 
     185             : /* {{{ proto Exception Exception::__clone()
     186             :    Clone the exception object */
     187           0 : ZEND_METHOD(exception, __clone)
     188             : {
     189             :         /* Should never be executable */
     190           0 :         zend_throw_exception(NULL, "Cannot clone object using __clone()", 0 TSRMLS_CC);
     191           0 : }
     192             : /* }}} */
     193             : 
     194             : /* {{{ proto Exception::__construct(string message, int code [, Exception previous])
     195             :    Exception constructor */
     196         307 : ZEND_METHOD(exception, __construct)
     197             : {
     198         307 :         zend_string *message = NULL;
     199         307 :         zend_long   code = 0;
     200         307 :         zval  *object, *previous = NULL;
     201         307 :         int    argc = ZEND_NUM_ARGS();
     202             : 
     203         307 :         if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc TSRMLS_CC, "|SlO!", &message, &code, &previous, default_exception_ce) == FAILURE) {
     204           0 :                 zend_error(E_ERROR, "Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]])");
     205             :         }
     206             : 
     207         307 :         object = getThis();
     208             : 
     209         307 :         if (message) {
     210         219 :                 zend_update_property_str(default_exception_ce, object, "message", sizeof("message")-1, message TSRMLS_CC);
     211             :         }
     212             : 
     213         307 :         if (code) {
     214           6 :                 zend_update_property_long(default_exception_ce, object, "code", sizeof("code")-1, code TSRMLS_CC);
     215             :         }
     216             : 
     217         307 :         if (previous) {
     218           3 :                 zend_update_property(default_exception_ce, object, "previous", sizeof("previous")-1, previous TSRMLS_CC);
     219             :         }
     220         307 : }
     221             : /* }}} */
     222             : 
     223             : /* {{{ proto ErrorException::__construct(string message, int code, int severity [, string filename [, int lineno [, Exception previous]]])
     224             :    ErrorException constructor */
     225           2 : ZEND_METHOD(error_exception, __construct)
     226             : {
     227           2 :         char  *message = NULL, *filename = NULL;
     228           2 :         zend_long   code = 0, severity = E_ERROR, lineno;
     229           2 :         zval  *object, *previous = NULL;
     230           2 :         int    argc = ZEND_NUM_ARGS();
     231             :         size_t message_len, filename_len;
     232             : 
     233           2 :         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) {
     234           0 :                 zend_error(E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno  [, Exception $previous = NULL]]]]]])");
     235             :         }
     236             : 
     237           2 :         object = getThis();
     238             : 
     239           2 :         if (message) {
     240           2 :                 zend_update_property_string(default_exception_ce, object, "message", sizeof("message")-1, message TSRMLS_CC);
     241             :         }
     242             : 
     243           2 :         if (code) {
     244           1 :                 zend_update_property_long(default_exception_ce, object, "code", sizeof("code")-1, code TSRMLS_CC);
     245             :         }
     246             : 
     247           2 :         if (previous) {
     248           0 :                 zend_update_property(default_exception_ce, object, "previous", sizeof("previous")-1, previous TSRMLS_CC);
     249             :         }
     250             : 
     251           2 :         zend_update_property_long(default_exception_ce, object, "severity", sizeof("severity")-1, severity TSRMLS_CC);
     252             : 
     253           2 :         if (argc >= 4) {
     254           2 :             zend_update_property_string(default_exception_ce, object, "file", sizeof("file")-1, filename TSRMLS_CC);
     255           2 :         if (argc < 5) {
     256           0 :             lineno = 0; /* invalidate lineno */
     257             :         }
     258           2 :         zend_update_property_long(default_exception_ce, object, "line", sizeof("line")-1, lineno TSRMLS_CC);
     259             :         }
     260           2 : }
     261             : /* }}} */
     262             : 
     263             : #define DEFAULT_0_PARAMS \
     264             :         if (zend_parse_parameters_none() == FAILURE) { \
     265             :                 return; \
     266             :         }
     267             : 
     268        1365 : static void _default_exception_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC) /* {{{ */
     269             : {
     270             :         zval *value;
     271             : 
     272        1365 :         value = zend_read_property(default_exception_ce, object, name, name_len, 0 TSRMLS_CC);
     273        1365 :         ZVAL_COPY(return_value, value);
     274        1365 : }
     275             : /* }}} */
     276             : 
     277             : /* {{{ proto string Exception::getFile()
     278             :    Get the file in which the exception occurred */
     279           6 : ZEND_METHOD(exception, getFile)
     280             : {
     281           6 :         DEFAULT_0_PARAMS;
     282             : 
     283           5 :         _default_exception_get_entry(getThis(), "file", sizeof("file")-1, return_value TSRMLS_CC);
     284             : }
     285             : /* }}} */
     286             : 
     287             : /* {{{ proto int Exception::getLine()
     288             :    Get the line in which the exception occurred */
     289          13 : ZEND_METHOD(exception, getLine)
     290             : {
     291          13 :         DEFAULT_0_PARAMS;
     292             : 
     293          12 :         _default_exception_get_entry(getThis(), "line", sizeof("line")-1, return_value TSRMLS_CC);
     294             : }
     295             : /* }}} */
     296             : 
     297             : /* {{{ proto string Exception::getMessage()
     298             :    Get the exception message */
     299         904 : ZEND_METHOD(exception, getMessage)
     300             : {
     301         904 :         DEFAULT_0_PARAMS;
     302             : 
     303         903 :         _default_exception_get_entry(getThis(), "message", sizeof("message")-1, return_value TSRMLS_CC);
     304             : }
     305             : /* }}} */
     306             : 
     307             : /* {{{ proto int Exception::getCode()
     308             :    Get the exception code */
     309          18 : ZEND_METHOD(exception, getCode)
     310             : {
     311          18 :         DEFAULT_0_PARAMS;
     312             : 
     313          17 :         _default_exception_get_entry(getThis(), "code", sizeof("code")-1, return_value TSRMLS_CC);
     314             : }
     315             : /* }}} */
     316             : 
     317             : /* {{{ proto array Exception::getTrace()
     318             :    Get the stack trace for the location in which the exception occurred */
     319           6 : ZEND_METHOD(exception, getTrace)
     320             : {
     321           6 :         DEFAULT_0_PARAMS;
     322             : 
     323           5 :         _default_exception_get_entry(getThis(), "trace", sizeof("trace")-1, return_value TSRMLS_CC);
     324             : }
     325             : /* }}} */
     326             : 
     327             : /* {{{ proto int ErrorException::getSeverity()
     328             :    Get the exception severity */
     329           0 : ZEND_METHOD(error_exception, getSeverity)
     330             : {
     331           0 :         DEFAULT_0_PARAMS;
     332             : 
     333           0 :         _default_exception_get_entry(getThis(), "severity", sizeof("severity")-1, return_value TSRMLS_CC);
     334             : }
     335             : /* }}} */
     336             : 
     337             : /* {{{ gettraceasstring() macros */
     338             : #define TRACE_APPEND_CHR(chr)                                        \
     339             :         str = zend_string_realloc(str, str->len + 1, 0);                         \
     340             :     str->val[str->len - 1] = chr
     341             : 
     342             : #define TRACE_APPEND_STRL(v, l)                                      \
     343             :         {                                                                \
     344             :                 str = zend_string_realloc(str, str->len + (l), 0);                   \
     345             :                 memcpy(str->val + str->len - (l), (v), (l));                 \
     346             :         }
     347             : 
     348             : #define TRACE_APPEND_STR(v)                                          \
     349             :         TRACE_APPEND_STRL((v), sizeof((v))-1)
     350             : 
     351             : #define TRACE_APPEND_KEY(key) do {                                          \
     352             :                 tmp = zend_hash_str_find(ht, key, sizeof(key)-1);                   \
     353             :                 if (tmp) {                                                          \
     354             :                         if (Z_TYPE_P(tmp) != IS_STRING) {                               \
     355             :                                 zend_error(E_WARNING, "Value for %s is no string", key);    \
     356             :                                 TRACE_APPEND_STR("[unknown]");                              \
     357             :                         } else {                                                        \
     358             :                                 TRACE_APPEND_STRL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp));        \
     359             :                         }                                                               \
     360             :                 } \
     361             :         } while (0)
     362             : 
     363             : 
     364             : #define TRACE_ARG_APPEND(vallen) do { \
     365             :                 int len = str->len; \
     366             :                 str = zend_string_realloc(str, len + vallen, 0); \
     367             :                 memmove(str->val + len - l_added + 1 + vallen, str->val + len - l_added + 1, l_added); \
     368             :         } while (0)
     369             : 
     370             : /* }}} */
     371             : 
     372         241 : static void _build_trace_args(zval *arg, zend_string **str_ptr TSRMLS_DC) /* {{{ */
     373             : {
     374         241 :         zend_string *str = *str_ptr;
     375             : 
     376             :         /* the trivial way would be to do:
     377             :          * convert_to_string_ex(arg);
     378             :          * append it and kill the now tmp arg.
     379             :          * but that could cause some E_NOTICE and also damn long lines.
     380             :          */
     381             : 
     382         241 :         ZVAL_DEREF(arg);
     383         241 :         switch (Z_TYPE_P(arg)) {
     384             :                 case IS_NULL:
     385           0 :                         TRACE_APPEND_STR("NULL, ");
     386           0 :                         break;
     387             :                 case IS_STRING: {
     388             :                         int l_added;
     389         288 :                         TRACE_APPEND_CHR('\'');
     390         144 :                         if (Z_STRLEN_P(arg) > 15) {
     391         106 :                                 TRACE_APPEND_STRL(Z_STRVAL_P(arg), 15);
     392         106 :                                 TRACE_APPEND_STR("...', ");
     393          53 :                                 l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */
     394             :                         } else {
     395          91 :                                 l_added = Z_STRLEN_P(arg);
     396         182 :                                 TRACE_APPEND_STRL(Z_STRVAL_P(arg), l_added);
     397         182 :                                 TRACE_APPEND_STR("', ");
     398          91 :                                 l_added += 3 + 1;
     399             :                         }
     400        2206 :                         while (--l_added) {
     401        1918 :                                 unsigned char chr = str->val[str->len - l_added];
     402        1918 :                                 if (chr < 32 || chr == '\\' || chr > 126) {
     403           5 :                                         str->val[str->len - l_added] = '\\';
     404             : 
     405           5 :                                         switch (chr) {
     406             :                                                 case '\n':
     407           0 :                                                         TRACE_ARG_APPEND(1);
     408           0 :                                                         str->val[str->len - l_added] = 'n';
     409           0 :                                                         break;
     410             :                                                 case '\r':
     411           0 :                                                         TRACE_ARG_APPEND(1);
     412           0 :                                                         str->val[str->len - l_added] = 'r';
     413           0 :                                                         break;
     414             :                                                 case '\t':
     415           0 :                                                         TRACE_ARG_APPEND(1);
     416           0 :                                                         str->val[str->len - l_added] = 't';
     417           0 :                                                         break;
     418             :                                                 case '\f':
     419           0 :                                                         TRACE_ARG_APPEND(1);
     420           0 :                                                         str->val[str->len - l_added] = 'f';
     421           0 :                                                         break;
     422             :                                                 case '\v':
     423           0 :                                                         TRACE_ARG_APPEND(1);
     424           0 :                                                         str->val[str->len - l_added] = 'v';
     425           0 :                                                         break;
     426             : #ifndef PHP_WIN32
     427             :                                                 case '\e':
     428             : #else
     429             :                                                 case VK_ESCAPE:
     430             : #endif
     431           0 :                                                         TRACE_ARG_APPEND(1);
     432           0 :                                                         str->val[str->len - l_added] = 'e';
     433           0 :                                                         break;
     434             :                                                 case '\\':
     435           0 :                                                         TRACE_ARG_APPEND(1);
     436           0 :                                                         str->val[str->len - l_added] = '\\';
     437           0 :                                                         break;
     438             :                                                 default:
     439          10 :                                                         TRACE_ARG_APPEND(3);
     440           5 :                                                         str->val[str->len - l_added - 2] = 'x';
     441           5 :                                                         if ((chr >> 4) < 10) {
     442           5 :                                                                 str->val[str->len - l_added - 1] = (chr >> 4) + '0';
     443             :                                                         } else {
     444           0 :                                                                 str->val[str->len - l_added - 1] = (chr >> 4) + 'A' - 10;
     445             :                                                         }
     446           5 :                                                         if (chr % 16 < 10) {
     447           5 :                                                                 str->val[str->len - l_added] = chr % 16 + '0';
     448             :                                                         } else {
     449           0 :                                                                 str->val[str->len - l_added] = chr % 16 + 'A' - 10;
     450             :                                                         }
     451             :                                         }
     452             :                                 }
     453             :                         }
     454         144 :                         break;
     455             :                 }
     456             :                 case IS_FALSE:
     457           0 :                         TRACE_APPEND_STR("false, ");
     458           0 :                         break;
     459             :                 case IS_TRUE:
     460           2 :                         TRACE_APPEND_STR("true, ");
     461           1 :                         break;
     462             :                 case IS_RESOURCE: {
     463           1 :                         zend_long lval = Z_RES_HANDLE_P(arg);
     464             :                         char s_tmp[MAX_LENGTH_OF_LONG + 1];
     465           1 :                         int l_tmp = zend_sprintf(s_tmp, ZEND_LONG_FMT, lval);  /* SAFE */
     466           2 :                         TRACE_APPEND_STR("Resource id #");
     467           2 :                         TRACE_APPEND_STRL(s_tmp, l_tmp);
     468           2 :                         TRACE_APPEND_STR(", ");
     469           1 :                         break;
     470             :                 }
     471             :                 case IS_LONG: {
     472          32 :                         zend_long lval = Z_LVAL_P(arg);
     473             :                         char s_tmp[MAX_LENGTH_OF_LONG + 1];
     474          32 :                         int l_tmp = zend_sprintf(s_tmp, ZEND_LONG_FMT, lval);  /* SAFE */
     475          64 :                         TRACE_APPEND_STRL(s_tmp, l_tmp);
     476          64 :                         TRACE_APPEND_STR(", ");
     477          32 :                         break;
     478             :                 }
     479             :                 case IS_DOUBLE: {
     480           0 :                         double dval = Z_DVAL_P(arg);
     481             :                         char *s_tmp;
     482             :                         int l_tmp;
     483             : 
     484           0 :                         s_tmp = emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1);
     485           0 :                         l_tmp = zend_sprintf(s_tmp, "%.*G", (int) EG(precision), dval);  /* SAFE */
     486           0 :                         TRACE_APPEND_STRL(s_tmp, l_tmp);
     487             :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     488           0 :                         efree(s_tmp);
     489           0 :                         TRACE_APPEND_STR(", ");
     490           0 :                         break;
     491             :                 }
     492             :                 case IS_ARRAY:
     493          82 :                         TRACE_APPEND_STR("Array, ");
     494          41 :                         break;
     495             :                 case IS_OBJECT: {
     496             :                         zend_string *class_name;
     497             : 
     498          44 :                         TRACE_APPEND_STR("Object(");
     499             : 
     500          22 :                         class_name = zend_get_object_classname(Z_OBJ_P(arg) TSRMLS_CC);
     501             : 
     502          44 :                         TRACE_APPEND_STRL(class_name->val, class_name->len);
     503          44 :                         TRACE_APPEND_STR("), ");
     504             :                         break;
     505             :                 }
     506             :                 default:
     507             :                         break;
     508             :         }
     509         241 :         *str_ptr = str;
     510         241 : }
     511             : /* }}} */
     512             : 
     513         178 : static void _build_trace_string(zval *frame, zend_ulong index, zend_string **str_ptr, int *num TSRMLS_DC) /* {{{ */
     514             : {
     515             :         char *s_tmp;
     516             :         int len;
     517             :         zend_long line;
     518             :         HashTable *ht;
     519             :         zval *file, *tmp;
     520         178 :         zend_string *str = *str_ptr;
     521             : 
     522         178 :         if (Z_TYPE_P(frame) != IS_ARRAY) {
     523           1 :                 zend_error(E_WARNING, "Expected array for frame %pu", index);
     524           1 :                 return;
     525             :         }
     526             : 
     527         177 :         ht = Z_ARRVAL_P(frame);
     528         177 :         s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1);
     529         177 :         len = sprintf(s_tmp, "#%d ", (*num)++);
     530         354 :         TRACE_APPEND_STRL(s_tmp, len);
     531         177 :         efree(s_tmp);
     532         177 :         file = zend_hash_str_find(ht, "file", sizeof("file")-1);
     533         177 :         if (file) {
     534         137 :                 if (Z_TYPE_P(file) != IS_STRING) {
     535           1 :                         zend_error(E_WARNING, "Function name is no string");
     536           2 :                         TRACE_APPEND_STR("[unknown function]");
     537             :                 } else{
     538         136 :                         tmp = zend_hash_str_find(ht, "line", sizeof("line")-1);
     539         136 :                         if (tmp) {
     540         136 :                                 if (Z_TYPE_P(tmp) == IS_LONG) {
     541         136 :                                         line = Z_LVAL_P(tmp);
     542             :                                 } else {
     543           0 :                                         zend_error(E_WARNING, "Line is no long");
     544           0 :                                         line = 0;
     545             :                                 }
     546             :                         } else {
     547           0 :                                 line = 0;
     548             :                         }
     549         136 :                         s_tmp = emalloc(Z_STRLEN_P(file) + MAX_LENGTH_OF_LONG + 4 + 1);
     550         136 :                         len = sprintf(s_tmp, "%s(" ZEND_LONG_FMT "): ", Z_STRVAL_P(file), line);
     551         272 :                         TRACE_APPEND_STRL(s_tmp, len);
     552         136 :                         efree(s_tmp);
     553             :                 }
     554             :         } else {
     555          80 :                 TRACE_APPEND_STR("[internal function]: ");
     556             :         }
     557         291 :         TRACE_APPEND_KEY("class");
     558         291 :         TRACE_APPEND_KEY("type");
     559         353 :         TRACE_APPEND_KEY("function");
     560         354 :         TRACE_APPEND_CHR('(');
     561         177 :         tmp = zend_hash_str_find(ht, "args", sizeof("args")-1);
     562         177 :         if (tmp) {
     563         175 :                 if (Z_TYPE_P(tmp) == IS_ARRAY) {
     564         174 :                         int last_len = str->len;
     565             :                         zval *arg;
     566             :                         
     567         415 :                         ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(tmp), arg) {
     568         241 :                                 _build_trace_args(arg, &str TSRMLS_CC);
     569             :                         } ZEND_HASH_FOREACH_END();
     570             : 
     571         174 :                         if (last_len != str->len) {
     572         123 :                                 str->len -= 2; /* remove last ', ' */
     573             :                         }
     574             :                 } else {
     575           1 :                         zend_error(E_WARNING, "args element is no array");
     576             :                 }
     577             :         }
     578         354 :         TRACE_APPEND_STR(")\n");
     579         177 :         *str_ptr = str;
     580             : }
     581             : /* }}} */
     582             : 
     583             : /* {{{ proto string Exception::getTraceAsString()
     584             :    Obtain the backtrace for the exception as a string (instead of an array) */
     585         147 : ZEND_METHOD(exception, getTraceAsString)
     586             : {
     587             :         zval *trace, *frame;
     588             :         zend_ulong index;
     589             :         zend_string *str;
     590         147 :         int num = 0, len;
     591             :         char s_tmp[MAX_LENGTH_OF_LONG + 7 + 1 + 1];
     592             : 
     593         147 :         DEFAULT_0_PARAMS;
     594             :         
     595         146 :         str = zend_string_alloc(0, 0);
     596             : 
     597         146 :         trace = zend_read_property(default_exception_ce, getThis(), "trace", sizeof("trace")-1, 1 TSRMLS_CC);
     598         324 :         ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(trace), index, frame) {
     599         178 :                 _build_trace_string(frame, index, &str, &num TSRMLS_CC);
     600             :         } ZEND_HASH_FOREACH_END();
     601             : 
     602         146 :         len = sprintf(s_tmp, "#%d {main}", num);
     603         292 :         TRACE_APPEND_STRL(s_tmp, len);
     604             : 
     605         146 :         str->val[str->len] = '\0';        
     606             : 
     607         146 :         RETURN_NEW_STR(str); 
     608             : }
     609             : /* }}} */
     610             : 
     611             : /* {{{ proto string Exception::getPrevious()
     612             :    Return previous Exception or NULL. */
     613           9 : ZEND_METHOD(exception, getPrevious)
     614             : {
     615             :         zval *previous;
     616             : 
     617           9 :         DEFAULT_0_PARAMS;
     618             : 
     619           9 :         previous = zend_read_property(default_exception_ce, getThis(), "previous", sizeof("previous")-1, 1 TSRMLS_CC);
     620          18 :         RETURN_ZVAL(previous, 1, 0);
     621             : } /* }}} */
     622             : 
     623        2846 : int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ */
     624             : {
     625             :         va_list arg;
     626             :         int len;
     627             : 
     628        2846 :         va_start(arg, format);
     629        2846 :         len = zend_vspprintf(message, max_len, format, arg);
     630        2846 :         va_end(arg);
     631        2846 :         return len;
     632             : }
     633             : /* }}} */
     634             : 
     635        9611 : zend_string *zend_strpprintf(int max_len, const char *format, ...) /* {{{ */
     636             : {
     637             :         va_list arg;
     638             :         zend_string *str;
     639             : 
     640        9611 :         va_start(arg, format);
     641        9611 :         str = zend_vstrpprintf(max_len, format, arg);
     642        9611 :         va_end(arg);
     643        9611 :         return str;
     644             : }
     645             : /* }}} */
     646             : 
     647             : /* {{{ proto string Exception::__toString()
     648             :    Obtain the string representation of the Exception object */
     649         135 : ZEND_METHOD(exception, __toString)
     650             : {
     651             :         zval message, file, line, trace, *exception;
     652             :         zend_string *str, *prev_str;
     653             :         zend_fcall_info fci;
     654             :         zval fname;
     655             :         
     656         135 :         DEFAULT_0_PARAMS;
     657             :         
     658         134 :         str = STR_EMPTY_ALLOC();
     659             : 
     660         134 :         exception = getThis();
     661         268 :         ZVAL_STRINGL(&fname, "gettraceasstring", sizeof("gettraceasstring")-1);
     662             : 
     663         408 :         while (exception && Z_TYPE_P(exception) == IS_OBJECT) {
     664         141 :                 prev_str = str;
     665         141 :                 _default_exception_get_entry(exception, "message", sizeof("message")-1, &message TSRMLS_CC);
     666         141 :                 _default_exception_get_entry(exception, "file", sizeof("file")-1, &file TSRMLS_CC);
     667         141 :                 _default_exception_get_entry(exception, "line", sizeof("line")-1, &line TSRMLS_CC);
     668             : 
     669         141 :                 convert_to_string_ex(&message);
     670         140 :                 convert_to_string_ex(&file);
     671         144 :                 convert_to_long_ex(&line);
     672             : 
     673         140 :                 fci.size = sizeof(fci);
     674         140 :                 fci.function_table = &Z_OBJCE_P(exception)->function_table;
     675         140 :                 ZVAL_COPY_VALUE(&fci.function_name, &fname);
     676         140 :                 fci.symbol_table = NULL;
     677         140 :                 fci.object = Z_OBJ_P(exception);
     678         140 :                 fci.retval = &trace;
     679         140 :                 fci.param_count = 0;
     680         140 :                 fci.params = NULL;
     681         140 :                 fci.no_separation = 1;
     682             : 
     683         140 :                 zend_call_function(&fci, NULL TSRMLS_CC);
     684             : 
     685         140 :                 if (Z_TYPE(trace) != IS_STRING) {
     686           0 :                         zval_ptr_dtor(&trace);
     687           0 :                         ZVAL_UNDEF(&trace);
     688             :                 }
     689             : 
     690         140 :                 if (Z_STRLEN(message) > 0) {
     691         928 :                         str = zend_strpprintf(0, "exception '%s' with message '%s' in %s:%ld\nStack trace:\n%s%s%s",
     692         348 :                                         Z_OBJCE_P(exception)->name->val, Z_STRVAL(message), Z_STRVAL(file), Z_LVAL(line),
     693         348 :                                         (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
     694         116 :                                         prev_str->len ? "\n\nNext " : "", prev_str->val);
     695             :                 } else {
     696         168 :                         str = zend_strpprintf(0, "exception '%s' in %s:%ld\nStack trace:\n%s%s%s",
     697          48 :                                         Z_OBJCE_P(exception)->name->val, Z_STRVAL(file), Z_LVAL(line),
     698          72 :                                         (Z_TYPE(trace) == IS_STRING && Z_STRLEN(trace)) ? Z_STRVAL(trace) : "#0 {main}\n",
     699          24 :                                         prev_str->len ? "\n\nNext " : "", prev_str->val);
     700             :                 }
     701             :                 zend_string_release(prev_str);
     702             :                 zval_dtor(&message);
     703             :                 zval_dtor(&file);
     704             :                 zval_dtor(&line);
     705             : 
     706         140 :                 exception = zend_read_property(default_exception_ce, exception, "previous", sizeof("previous")-1, 0 TSRMLS_CC);
     707             : 
     708         140 :                 zval_ptr_dtor(&trace);
     709             : 
     710             :         }
     711             :         zval_dtor(&fname);
     712             : 
     713             :         /* We store the result in the private property string so we can access
     714             :          * the result in uncaught exception handlers without memleaks. */
     715         133 :         zend_update_property_str(default_exception_ce, getThis(), "string", sizeof("string")-1, str TSRMLS_CC);
     716             : 
     717         133 :         RETURN_STR(str);
     718             : }
     719             : /* }}} */
     720             : 
     721             : /* {{{ internal structs */
     722             : /* All functions that may be used in uncaught exception handlers must be final
     723             :  * and must not throw exceptions. Otherwise we would need a facility to handle
     724             :  * such exceptions in that handler.
     725             :  * Also all getXY() methods are final because thy serve as read only access to
     726             :  * their corresponding properties, no more, no less. If after all you need to
     727             :  * override somthing then it is method __toString().
     728             :  * And never try to change the state of exceptions and never implement anything
     729             :  * that gives the user anything to accomplish this.
     730             :  */
     731             : ZEND_BEGIN_ARG_INFO_EX(arginfo_exception___construct, 0, 0, 0)
     732             :         ZEND_ARG_INFO(0, message)
     733             :         ZEND_ARG_INFO(0, code)
     734             :         ZEND_ARG_INFO(0, previous)
     735             : ZEND_END_ARG_INFO()
     736             : 
     737             : const static zend_function_entry default_exception_functions[] = {
     738             :         ZEND_ME(exception, __clone, NULL, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL)
     739             :         ZEND_ME(exception, __construct, arginfo_exception___construct, ZEND_ACC_PUBLIC)
     740             :         ZEND_ME(exception, getMessage, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     741             :         ZEND_ME(exception, getCode, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     742             :         ZEND_ME(exception, getFile, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     743             :         ZEND_ME(exception, getLine, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     744             :         ZEND_ME(exception, getTrace, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     745             :         ZEND_ME(exception, getPrevious, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     746             :         ZEND_ME(exception, getTraceAsString, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     747             :         ZEND_ME(exception, __toString, NULL, 0)
     748             :         {NULL, NULL, NULL}
     749             : };
     750             : 
     751             : ZEND_BEGIN_ARG_INFO_EX(arginfo_error_exception___construct, 0, 0, 0)
     752             :         ZEND_ARG_INFO(0, message)
     753             :         ZEND_ARG_INFO(0, code)
     754             :         ZEND_ARG_INFO(0, severity)
     755             :         ZEND_ARG_INFO(0, filename)
     756             :         ZEND_ARG_INFO(0, lineno)
     757             :         ZEND_ARG_INFO(0, previous)
     758             : ZEND_END_ARG_INFO()
     759             : 
     760             : static const zend_function_entry error_exception_functions[] = {
     761             :         ZEND_ME(error_exception, __construct, arginfo_error_exception___construct, ZEND_ACC_PUBLIC)
     762             :         ZEND_ME(error_exception, getSeverity, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
     763             :         {NULL, NULL, NULL}
     764             : };
     765             : /* }}} */
     766             : 
     767       20335 : void zend_register_default_exception(TSRMLS_D) /* {{{ */
     768             : {
     769             :         zend_class_entry ce;
     770             : 
     771       20335 :         INIT_CLASS_ENTRY(ce, "Exception", default_exception_functions);
     772       20335 :         default_exception_ce = zend_register_internal_class(&ce TSRMLS_CC);
     773       20335 :         default_exception_ce->create_object = zend_default_exception_new;
     774       20335 :         memcpy(&default_exception_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
     775       20335 :         default_exception_handlers.clone_obj = NULL;
     776             : 
     777       20335 :         zend_declare_property_string(default_exception_ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED TSRMLS_CC);
     778       20335 :         zend_declare_property_string(default_exception_ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE TSRMLS_CC);
     779       20335 :         zend_declare_property_long(default_exception_ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED TSRMLS_CC);
     780       20335 :         zend_declare_property_null(default_exception_ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
     781       20335 :         zend_declare_property_null(default_exception_ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED TSRMLS_CC);
     782       20335 :         zend_declare_property_null(default_exception_ce, "trace", sizeof("trace")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     783       20335 :         zend_declare_property_null(default_exception_ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE TSRMLS_CC);
     784             : 
     785       20335 :         INIT_CLASS_ENTRY(ce, "ErrorException", error_exception_functions);
     786       20335 :         error_exception_ce = zend_register_internal_class_ex(&ce, default_exception_ce TSRMLS_CC);
     787       20335 :         error_exception_ce->create_object = zend_error_exception_new;
     788       20335 :         zend_declare_property_long(error_exception_ce, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED TSRMLS_CC);
     789       20335 : }
     790             : /* }}} */
     791             : 
     792      142814 : ZEND_API zend_class_entry *zend_exception_get_default(TSRMLS_D) /* {{{ */
     793             : {
     794      142814 :         return default_exception_ce;
     795             : }
     796             : /* }}} */
     797             : 
     798           0 : ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D) /* {{{ */
     799             : {
     800           0 :         return error_exception_ce;
     801             : }
     802             : /* }}} */
     803             : 
     804         889 : ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code TSRMLS_DC) /* {{{ */
     805             : {
     806             :         zval ex;
     807             : 
     808         889 :         if (exception_ce) {
     809         760 :                 if (!instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
     810           0 :                         zend_error(E_NOTICE, "Exceptions must be derived from the Exception base class");
     811           0 :                         exception_ce = default_exception_ce;
     812             :                 }
     813             :         } else {
     814         129 :                 exception_ce = default_exception_ce;
     815             :         }
     816         889 :         object_init_ex(&ex, exception_ce);
     817             : 
     818             : 
     819         889 :         if (message) {
     820         889 :                 zend_update_property_string(default_exception_ce, &ex, "message", sizeof("message")-1, message TSRMLS_CC);
     821             :         }
     822         889 :         if (code) {
     823          94 :                 zend_update_property_long(default_exception_ce, &ex, "code", sizeof("code")-1, code TSRMLS_CC);
     824             :         }
     825             : 
     826         889 :         zend_throw_exception_internal(&ex TSRMLS_CC);
     827         889 :         return Z_OBJ(ex);
     828             : }
     829             : /* }}} */
     830             : 
     831         583 : ZEND_API zend_object *zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code TSRMLS_DC, const char *format, ...) /* {{{ */
     832             : {
     833             :         va_list arg;
     834             :         char *message;
     835             :         zend_object *obj;
     836             : 
     837         583 :         va_start(arg, format);
     838         583 :         zend_vspprintf(&message, 0, format, arg);
     839         583 :         va_end(arg);
     840         583 :         obj = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
     841         583 :         efree(message);
     842         583 :         return obj;
     843             : }
     844             : /* }}} */
     845             : 
     846         144 : ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, zend_long code, int severity TSRMLS_DC) /* {{{ */
     847             : {
     848             :         zval ex;
     849         144 :         zend_object *obj = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
     850         144 :         ZVAL_OBJ(&ex, obj);
     851         144 :         zend_update_property_long(default_exception_ce, &ex, "severity", sizeof("severity")-1, severity TSRMLS_CC);
     852         144 :         return obj;
     853             : }
     854             : /* }}} */
     855             : 
     856         106 : static void zend_error_va(int type, const char *file, uint lineno, const char *format, ...) /* {{{ */
     857             : {
     858             :         va_list args;
     859             : 
     860         106 :         va_start(args, format);
     861         106 :         zend_error_cb(type, file, lineno, format, args);
     862           3 :         va_end(args);
     863           3 : }
     864             : /* }}} */
     865             : 
     866             : /* This function doesn't return if it uses E_ERROR */
     867         107 : ZEND_API void zend_exception_error(zend_object *ex, int severity TSRMLS_DC) /* {{{ */
     868             : {
     869             :         zval exception;
     870             :         zend_class_entry *ce_exception;
     871             :         
     872         107 :         ZVAL_OBJ(&exception, ex);
     873         107 :         ce_exception = Z_OBJCE(exception);
     874         107 :         if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
     875             :                 zval tmp, *str, *file, *line;
     876             : 
     877         107 :                 EG(exception) = NULL;
     878             : 
     879         107 :                 zend_call_method_with_0_params(&exception, ce_exception, NULL, "__tostring", &tmp);
     880         106 :                 if (!EG(exception)) {
     881         106 :                         if (Z_TYPE(tmp) != IS_STRING) {
     882           0 :                                 zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name->val);
     883             :                         } else {
     884         106 :                                 zend_update_property_string(default_exception_ce, &exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name->val : Z_STRVAL(tmp) TSRMLS_CC);
     885             :                         }
     886             :                 }
     887         106 :                 zval_ptr_dtor(&tmp);
     888             : 
     889         106 :                 if (EG(exception)) {
     890             :                         zval zv;
     891             : 
     892           0 :                         ZVAL_OBJ(&zv, EG(exception));
     893             :                         /* do the best we can to inform about the inner exception */
     894           0 :                         if (instanceof_function(ce_exception, default_exception_ce TSRMLS_CC)) {
     895           0 :                                 file = zend_read_property(default_exception_ce, &zv, "file", sizeof("file")-1, 1 TSRMLS_CC);
     896           0 :                                 line = zend_read_property(default_exception_ce, &zv, "line", sizeof("line")-1, 1 TSRMLS_CC);
     897             : 
     898           0 :                                 convert_to_string_ex(file);
     899           0 :                                 file = (Z_STRLEN_P(file) > 0) ? file : NULL;
     900           0 :                                 line = (Z_TYPE_P(line) == IS_LONG) ? line : NULL;
     901             :                         } else {
     902           0 :                                 file = NULL;
     903           0 :                                 line = NULL;
     904             :                         }
     905           0 :                         zend_error_va(E_WARNING, file ? Z_STRVAL_P(file) : NULL, line ? Z_LVAL_P(line) : 0, "Uncaught %s in exception handling during call to %s::__tostring()", Z_OBJCE(zv)->name->val, ce_exception->name->val);
     906             :                 }
     907             : 
     908         106 :                 str = zend_read_property(default_exception_ce, &exception, "string", sizeof("string")-1, 1 TSRMLS_CC);
     909         106 :                 file = zend_read_property(default_exception_ce, &exception, "file", sizeof("file")-1, 1 TSRMLS_CC);
     910         106 :                 line = zend_read_property(default_exception_ce, &exception, "line", sizeof("line")-1, 1 TSRMLS_CC);
     911             : 
     912         106 :                 convert_to_string_ex(str);
     913         106 :                 convert_to_string_ex(file);
     914         108 :                 convert_to_long_ex(line);
     915             : 
     916         106 :                 zend_error_va(severity, (Z_STRLEN_P(file) > 0) ? Z_STRVAL_P(file) : NULL, Z_LVAL_P(line), "Uncaught %s\n  thrown", Z_STRVAL_P(str));
     917             :         } else {
     918           0 :                 zend_error(severity, "Uncaught exception '%s'", ce_exception->name->val);
     919             :         }
     920           3 : }
     921             : /* }}} */
     922             : 
     923         365 : ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC) /* {{{ */
     924             : {
     925             :         zend_class_entry *exception_ce;
     926             : 
     927         365 :         if (exception == NULL || Z_TYPE_P(exception) != IS_OBJECT) {
     928           0 :                 zend_error(E_ERROR, "Need to supply an object when throwing an exception");
     929             :         }
     930             : 
     931         365 :         exception_ce = Z_OBJCE_P(exception);
     932             : 
     933         365 :         if (!exception_ce || !instanceof_function(exception_ce, default_exception_ce TSRMLS_CC)) {
     934           2 :                 zend_error(E_ERROR, "Exceptions must be valid objects derived from the Exception base class");
     935             :         }
     936         363 :         zend_throw_exception_internal(exception TSRMLS_CC);
     937         363 : }
     938             : /* }}} */
     939             : 
     940             : /*
     941             :  * Local variables:
     942             :  * tab-width: 4
     943             :  * c-basic-offset: 4
     944             :  * indent-tabs-mode: t
     945             :  * End:
     946             :  */

Generated by: LCOV version 1.10

Generated at Fri, 19 Sep 2014 17:11:03 +0000 (46 hours ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.