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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_HEAD/Zend - zend_exceptions.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 381
Code covered: 86.6 % Executed lines: 330
Legend: not executed executed

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

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:26 +0000 (34 hours ago)

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