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_5_2/Zend - zend_builtin_functions.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 935
Code covered: 88.6 % Executed lines: 828
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                 :    |          Zeev Suraski <zeev@zend.com>                                |
      17                 :    +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: zend_builtin_functions.c 282907 2009-06-28 01:16:36Z felipe $ */
      21                 : 
      22                 : #include "zend.h"
      23                 : #include "zend_API.h"
      24                 : #include "zend_builtin_functions.h"
      25                 : #include "zend_constants.h"
      26                 : #include "zend_ini.h"
      27                 : #include "zend_exceptions.h"
      28                 : #include "zend_extensions.h"
      29                 : 
      30                 : #undef ZEND_TEST_EXCEPTIONS
      31                 : 
      32                 : static ZEND_FUNCTION(zend_version);
      33                 : static ZEND_FUNCTION(func_num_args);
      34                 : static ZEND_FUNCTION(func_get_arg);
      35                 : static ZEND_FUNCTION(func_get_args);
      36                 : static ZEND_FUNCTION(strlen);
      37                 : static ZEND_FUNCTION(strcmp);
      38                 : static ZEND_FUNCTION(strncmp);
      39                 : static ZEND_FUNCTION(strcasecmp);
      40                 : static ZEND_FUNCTION(strncasecmp);
      41                 : static ZEND_FUNCTION(each);
      42                 : static ZEND_FUNCTION(error_reporting);
      43                 : static ZEND_FUNCTION(define);
      44                 : static ZEND_FUNCTION(defined);
      45                 : static ZEND_FUNCTION(get_class);
      46                 : static ZEND_FUNCTION(get_parent_class);
      47                 : static ZEND_FUNCTION(method_exists);
      48                 : static ZEND_FUNCTION(property_exists);
      49                 : static ZEND_FUNCTION(class_exists);
      50                 : static ZEND_FUNCTION(interface_exists);
      51                 : static ZEND_FUNCTION(function_exists);
      52                 : #if ZEND_DEBUG
      53                 : static ZEND_FUNCTION(leak);
      54                 : #ifdef ZEND_TEST_EXCEPTIONS
      55                 : static ZEND_FUNCTION(crash);
      56                 : #endif
      57                 : #endif
      58                 : static ZEND_FUNCTION(get_included_files);
      59                 : static ZEND_FUNCTION(is_subclass_of);
      60                 : static ZEND_FUNCTION(is_a);
      61                 : static ZEND_FUNCTION(get_class_vars);
      62                 : static ZEND_FUNCTION(get_object_vars);
      63                 : static ZEND_FUNCTION(get_class_methods);
      64                 : static ZEND_FUNCTION(trigger_error);
      65                 : static ZEND_FUNCTION(set_error_handler);
      66                 : static ZEND_FUNCTION(restore_error_handler);
      67                 : static ZEND_FUNCTION(set_exception_handler);
      68                 : static ZEND_FUNCTION(restore_exception_handler);
      69                 : static ZEND_FUNCTION(get_declared_classes);
      70                 : static ZEND_FUNCTION(get_declared_interfaces);
      71                 : static ZEND_FUNCTION(get_defined_functions);
      72                 : static ZEND_FUNCTION(get_defined_vars);
      73                 : static ZEND_FUNCTION(create_function);
      74                 : static ZEND_FUNCTION(get_resource_type);
      75                 : static ZEND_FUNCTION(get_loaded_extensions);
      76                 : static ZEND_FUNCTION(extension_loaded);
      77                 : static ZEND_FUNCTION(get_extension_funcs);
      78                 : static ZEND_FUNCTION(get_defined_constants);
      79                 : static ZEND_FUNCTION(debug_backtrace);
      80                 : static ZEND_FUNCTION(debug_print_backtrace);
      81                 : #if ZEND_DEBUG
      82                 : static ZEND_FUNCTION(zend_test_func);
      83                 : #ifdef ZTS
      84                 : static ZEND_FUNCTION(zend_thread_id);
      85                 : #endif
      86                 : #endif
      87                 : 
      88                 : #include "zend_arg_defs.c"
      89                 : 
      90                 : 
      91                 : static zend_function_entry builtin_functions[] = {
      92                 :         ZEND_FE(zend_version,           NULL)
      93                 :         ZEND_FE(func_num_args,          NULL)
      94                 :         ZEND_FE(func_get_arg,           NULL)
      95                 :         ZEND_FE(func_get_args,          NULL)
      96                 :         ZEND_FE(strlen,                         NULL)
      97                 :         ZEND_FE(strcmp,                         NULL)
      98                 :         ZEND_FE(strncmp,                        NULL)
      99                 :         ZEND_FE(strcasecmp,                     NULL)
     100                 :         ZEND_FE(strncasecmp,            NULL)
     101                 :         ZEND_FE(each,                           first_arg_force_ref)
     102                 :         ZEND_FE(error_reporting,        NULL)
     103                 :         ZEND_FE(define,                         NULL)
     104                 :         ZEND_FE(defined,                        NULL)
     105                 :         ZEND_FE(get_class,                      NULL)
     106                 :         ZEND_FE(get_parent_class,       NULL)
     107                 :         ZEND_FE(method_exists,          NULL)
     108                 :         ZEND_FE(property_exists,        NULL)
     109                 :         ZEND_FE(class_exists,           NULL)
     110                 :         ZEND_FE(interface_exists,       NULL)
     111                 :         ZEND_FE(function_exists,        NULL)
     112                 : #if ZEND_DEBUG
     113                 :         ZEND_FE(leak,                           NULL)
     114                 : #ifdef ZEND_TEST_EXCEPTIONS
     115                 :         ZEND_FE(crash,                          NULL)
     116                 : #endif
     117                 : #endif
     118                 :         ZEND_FE(get_included_files,     NULL)
     119                 :         ZEND_FALIAS(get_required_files, get_included_files,             NULL)
     120                 :         ZEND_FE(is_subclass_of,         NULL)
     121                 :         ZEND_FE(is_a,                           NULL)
     122                 :         ZEND_FE(get_class_vars,         NULL)
     123                 :         ZEND_FE(get_object_vars,        NULL)
     124                 :         ZEND_FE(get_class_methods,      NULL)
     125                 :         ZEND_FE(trigger_error,          NULL)
     126                 :         ZEND_FALIAS(user_error,         trigger_error,          NULL)
     127                 :         ZEND_FE(set_error_handler,              NULL)
     128                 :         ZEND_FE(restore_error_handler,  NULL)
     129                 :         ZEND_FE(set_exception_handler,          NULL)
     130                 :         ZEND_FE(restore_exception_handler,      NULL)
     131                 :         ZEND_FE(get_declared_classes, NULL)
     132                 :         ZEND_FE(get_declared_interfaces, NULL)
     133                 :         ZEND_FE(get_defined_functions, NULL)
     134                 :         ZEND_FE(get_defined_vars,       NULL)
     135                 :         ZEND_FE(create_function,        NULL)
     136                 :         ZEND_FE(get_resource_type,      NULL)
     137                 :         ZEND_FE(get_loaded_extensions,          NULL)
     138                 :         ZEND_FE(extension_loaded,                       NULL)
     139                 :         ZEND_FE(get_extension_funcs,            NULL)
     140                 :         ZEND_FE(get_defined_constants,          NULL)
     141                 :         ZEND_FE(debug_backtrace, NULL)
     142                 :         ZEND_FE(debug_print_backtrace, NULL)
     143                 : #if ZEND_DEBUG
     144                 :         ZEND_FE(zend_test_func,         NULL)
     145                 : #ifdef ZTS
     146                 :         ZEND_FE(zend_thread_id,         NULL)
     147                 : #endif
     148                 : #endif
     149                 :         { NULL, NULL, NULL }
     150                 : };
     151                 : 
     152                 : 
     153                 : int zend_startup_builtin_functions(TSRMLS_D)
     154           13565 : {
     155           13565 :         return zend_register_functions(NULL, builtin_functions, NULL, MODULE_PERSISTENT TSRMLS_CC);
     156                 : }
     157                 : 
     158                 : 
     159                 : /* {{{ proto string zend_version(void)
     160                 :    Get the version of the Zend Engine */
     161                 : ZEND_FUNCTION(zend_version)
     162             136 : {
     163             136 :         RETURN_STRINGL(ZEND_VERSION, sizeof(ZEND_VERSION)-1, 1);
     164                 : }
     165                 : /* }}} */
     166                 : 
     167                 : 
     168                 : /* {{{ proto int func_num_args(void)
     169                 :    Get the number of arguments that were passed to the function */
     170                 : ZEND_FUNCTION(func_num_args)
     171              16 : {
     172                 :         void **p;
     173                 :         int arg_count;
     174                 : 
     175              16 :         p = EG(argument_stack).top_element-1-1;
     176              16 :         arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_num_args(); */
     177              16 :         p -= 1+arg_count;
     178              16 :         if (*p) {
     179               0 :                 zend_error(E_ERROR, "func_num_args(): Can't be used as a function parameter");
     180                 :         }
     181              16 :         --p;
     182              16 :         if (p>=EG(argument_stack).elements) {
     183              14 :                 RETURN_LONG((long)(zend_uintptr_t) *p);
     184                 :         } else {
     185               2 :                 zend_error(E_WARNING, "func_num_args():  Called from the global scope - no function context");
     186               2 :                 RETURN_LONG(-1);
     187                 :         }
     188                 : }
     189                 : /* }}} */
     190                 : 
     191                 : 
     192                 : /* {{{ proto mixed func_get_arg(int arg_num)
     193                 :    Get the $arg_num'th argument that was passed to the function */
     194                 : ZEND_FUNCTION(func_get_arg)
     195              41 : {
     196                 :         void **p;
     197                 :         int arg_count;
     198                 :         zval **z_requested_offset;
     199                 :         zval *arg;
     200                 :         long requested_offset;
     201                 : 
     202              41 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &z_requested_offset)==FAILURE) {
     203               4 :                 RETURN_FALSE;
     204                 :         }
     205              37 :         convert_to_long_ex(z_requested_offset);
     206              37 :         requested_offset = Z_LVAL_PP(z_requested_offset);
     207                 : 
     208              37 :         if (requested_offset < 0) {
     209               4 :                 zend_error(E_WARNING, "func_get_arg():  The argument number should be >= 0");
     210               4 :                 RETURN_FALSE;
     211                 :         }
     212                 : 
     213              33 :         p = EG(argument_stack).top_element-1-1;
     214              33 :         arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_arg(); */
     215              33 :         p -= 1+arg_count;
     216              33 :         if (*p) {
     217               0 :                 zend_error(E_ERROR, "func_get_arg(): Can't be used as a function parameter");
     218                 :         }
     219              33 :         --p;
     220              33 :         if (p<EG(argument_stack).elements) {
     221               3 :                 zend_error(E_WARNING, "func_get_arg():  Called from the global scope - no function context");
     222               3 :                 RETURN_FALSE;
     223                 :         }
     224              30 :         arg_count = (int)(zend_uintptr_t) *p;
     225                 : 
     226              30 :         if (requested_offset>=arg_count) {
     227              16 :                 zend_error(E_WARNING, "func_get_arg():  Argument %ld not passed to function", requested_offset);
     228              16 :                 RETURN_FALSE;
     229                 :         }
     230                 : 
     231              14 :         arg = *(p-(arg_count-requested_offset));
     232              14 :         *return_value = *arg;
     233              14 :         zval_copy_ctor(return_value);
     234              14 :         INIT_PZVAL(return_value);
     235                 : }
     236                 : /* }}} */
     237                 : 
     238                 : 
     239                 : /* {{{ proto array func_get_args()
     240                 :    Get an array of the arguments that were passed to the function */
     241                 : ZEND_FUNCTION(func_get_args)
     242              59 : {
     243                 :         void **p;
     244                 :         int arg_count;
     245                 :         int i;
     246                 : 
     247              59 :         p = EG(argument_stack).top_element-1-1;
     248              59 :         arg_count = (int)(zend_uintptr_t) *p;           /* this is the amount of arguments passed to func_get_args(); */
     249              59 :         p -= 1+arg_count;
     250              59 :         if (*p) {
     251               0 :                 zend_error(E_ERROR, "func_get_args(): Can't be used as a function parameter");
     252                 :         }
     253              59 :         --p;
     254                 : 
     255              59 :         if (p<EG(argument_stack).elements) {
     256               2 :                 zend_error(E_WARNING, "func_get_args():  Called from the global scope - no function context");
     257               2 :                 RETURN_FALSE;
     258                 :         }
     259              57 :         arg_count = (int)(zend_uintptr_t) *p;
     260                 : 
     261                 : 
     262              57 :         array_init(return_value);
     263             117 :         for (i=0; i<arg_count; i++) {
     264                 :                 zval *element;
     265                 : 
     266              60 :                 ALLOC_ZVAL(element);
     267              60 :                 *element = **((zval **) (p-(arg_count-i)));
     268              60 :                 zval_copy_ctor(element);
     269              60 :                 INIT_PZVAL(element);
     270              60 :                 zend_hash_next_index_insert(return_value->value.ht, &element, sizeof(zval *), NULL);
     271                 :         }
     272                 : }
     273                 : /* }}} */
     274                 : 
     275                 : 
     276                 : /* {{{ proto int strlen(string str)
     277                 :    Get string length */
     278                 : ZEND_FUNCTION(strlen)
     279          636313 : {
     280                 :         zval **str;
     281                 : 
     282          636313 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &str) == FAILURE) {
     283               5 :                 ZEND_WRONG_PARAM_COUNT();
     284                 :         }
     285          636308 :         convert_to_string_ex(str);
     286          636308 :         RETVAL_LONG(Z_STRLEN_PP(str));
     287                 : }
     288                 : /* }}} */
     289                 : 
     290                 : 
     291                 : /* {{{ proto int strcmp(string str1, string str2)
     292                 :    Binary safe string comparison */
     293                 : ZEND_FUNCTION(strcmp)
     294          852147 : {
     295                 :         zval **s1, **s2;
     296                 :         
     297          852147 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) {
     298               4 :                 ZEND_WRONG_PARAM_COUNT();
     299                 :         }
     300          852143 :         convert_to_string_ex(s1);
     301          852143 :         convert_to_string_ex(s2);
     302          852143 :         RETURN_LONG(zend_binary_zval_strcmp(*s1, *s2));
     303                 : }
     304                 : /* }}} */
     305                 : 
     306                 : 
     307                 : /* {{{ proto int strncmp(string str1, string str2, int len)
     308                 :    Binary safe string comparison */
     309                 : ZEND_FUNCTION(strncmp)
     310            9789 : {
     311                 :         zval **s1, **s2, **s3;
     312                 :         
     313            9789 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &s1, &s2, &s3) == FAILURE) {
     314               5 :                 ZEND_WRONG_PARAM_COUNT();
     315                 :         }
     316            9784 :         convert_to_string_ex(s1);
     317            9784 :         convert_to_string_ex(s2);
     318            9784 :         convert_to_long_ex(s3);
     319                 : 
     320            9784 :         if (Z_LVAL_PP(s3) < 0) {
     321               3 :                 zend_error(E_WARNING, "Length must be greater than or equal to 0");
     322               3 :                 RETURN_FALSE;
     323                 :         }
     324                 :         
     325            9781 :         RETURN_LONG(zend_binary_zval_strncmp(*s1, *s2, *s3));
     326                 : }
     327                 : /* }}} */
     328                 : 
     329                 : 
     330                 : /* {{{ proto int strcasecmp(string str1, string str2)
     331                 :    Binary safe case-insensitive string comparison */
     332                 : ZEND_FUNCTION(strcasecmp)
     333            1035 : {
     334                 :         zval **s1, **s2;
     335                 :         
     336            1035 :         if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) {
     337               5 :                 ZEND_WRONG_PARAM_COUNT();
     338                 :         }
     339            1030 :         convert_to_string_ex(s1);
     340            1030 :         convert_to_string_ex(s2);
     341            1030 :         RETURN_LONG(zend_binary_zval_strcasecmp(*s1, *s2));
     342                 : }
     343                 : /* }}} */
     344                 : 
     345                 : 
     346                 : /* {{{ proto int strncasecmp(string str1, string str2, int len)
     347                 :    Binary safe string comparison */
     348                 : ZEND_FUNCTION(strncasecmp)
     349           13767 : {
     350                 :         zval **s1, **s2, **s3;
     351                 :         
     352           13767 :         if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &s1, &s2, &s3) == FAILURE) {
     353               5 :                 ZEND_WRONG_PARAM_COUNT();
     354                 :         }
     355           13762 :         convert_to_string_ex(s1);
     356           13762 :         convert_to_string_ex(s2);
     357           13762 :         convert_to_long_ex(s3);
     358                 : 
     359           13762 :         if (Z_LVAL_PP(s3) < 0) {
     360               3 :                 zend_error(E_WARNING, "Length must be greater than or equal to 0");
     361               3 :                 RETURN_FALSE;
     362                 :         }
     363                 : 
     364           13759 :         RETURN_LONG(zend_binary_zval_strncasecmp(*s1, *s2, *s3));
     365                 : }
     366                 : /* }}} */
     367                 : 
     368                 : 
     369                 : /* {{{ proto array each(array arr)
     370                 :    Return the currently pointed key..value pair in the passed array, and advance the pointer to the next element */
     371                 : ZEND_FUNCTION(each)
     372             219 : {
     373                 :         zval **array, *entry, **entry_ptr, *tmp;
     374                 :         char *string_key;
     375                 :         uint string_key_len;
     376                 :         ulong num_key;
     377                 :         zval **inserted_pointer;
     378                 :         HashTable *target_hash;
     379                 : 
     380             219 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &array) == FAILURE) {
     381               5 :                 ZEND_WRONG_PARAM_COUNT();
     382                 :         }
     383                 : 
     384             214 :         target_hash = HASH_OF(*array);
     385             214 :         if (!target_hash) {
     386              28 :                 zend_error(E_WARNING,"Variable passed to each() is not an array or object");
     387              28 :                 return;
     388                 :         }
     389             186 :         if (zend_hash_get_current_data(target_hash, (void **) &entry_ptr)==FAILURE) {
     390              37 :                 RETURN_FALSE;
     391                 :         }
     392             149 :         array_init(return_value);
     393             149 :         entry = *entry_ptr;
     394                 : 
     395                 :         /* add value elements */
     396             149 :         if (entry->is_ref) {
     397               3 :                 ALLOC_ZVAL(tmp);
     398               3 :                 *tmp = *entry;
     399               3 :                 zval_copy_ctor(tmp);
     400               3 :                 tmp->is_ref=0;
     401               3 :                 tmp->refcount=0;
     402               3 :                 entry=tmp;
     403                 :         }
     404             149 :         zend_hash_index_update(return_value->value.ht, 1, &entry, sizeof(zval *), NULL);
     405             149 :         entry->refcount++;
     406             149 :         zend_hash_update(return_value->value.ht, "value", sizeof("value"), &entry, sizeof(zval *), NULL);
     407             149 :         entry->refcount++;
     408                 : 
     409                 :         /* add the key elements */
     410             149 :         switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 1, NULL)) {
     411                 :                 case HASH_KEY_IS_STRING:
     412              35 :                         add_get_index_stringl(return_value, 0, string_key, string_key_len-1, (void **) &inserted_pointer, 0);
     413              35 :                         break;
     414                 :                 case HASH_KEY_IS_LONG:
     415             114 :                         add_get_index_long(return_value, 0, num_key, (void **) &inserted_pointer);
     416                 :                         break;
     417                 :         }
     418             149 :         zend_hash_update(return_value->value.ht, "key", sizeof("key"), inserted_pointer, sizeof(zval *), NULL);
     419             149 :         (*inserted_pointer)->refcount++;
     420             149 :         zend_hash_move_forward(target_hash);
     421                 : }
     422                 : /* }}} */
     423                 : 
     424                 : 
     425                 : /* {{{ proto int error_reporting(int new_error_level=null)
     426                 :    Return the current error_reporting level, and if an argument was passed - change to the new level */
     427                 : ZEND_FUNCTION(error_reporting)
     428            1775 : {
     429                 :         zval **arg;
     430                 :         int old_error_reporting;
     431                 : 
     432            1775 :         old_error_reporting = EG(error_reporting);
     433            1775 :         switch (ZEND_NUM_ARGS()) {
     434                 :                 case 0:
     435            1568 :                         break;
     436                 :                 case 1:
     437             207 :                         if (zend_get_parameters_ex(1, &arg) == FAILURE) {
     438               0 :                                 RETURN_FALSE;
     439                 :                         }
     440             207 :                         convert_to_string_ex(arg);
     441             207 :                         zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME);
     442             207 :                         break;
     443                 :                 default:
     444               0 :                         ZEND_WRONG_PARAM_COUNT();
     445                 :                         break;
     446                 :         }
     447                 : 
     448            1775 :         RETVAL_LONG(old_error_reporting);
     449                 : }
     450                 : /* }}} */
     451                 : 
     452                 : 
     453                 : /* {{{ proto bool define(string constant_name, mixed value, boolean case_sensitive=true)
     454                 :    Define a new constant */
     455                 : ZEND_FUNCTION(define)
     456             245 : {
     457                 :         char *name;
     458                 :         int name_len;
     459                 :         zval *val;
     460             245 :         zval *val_free = NULL;
     461             245 :         zend_bool non_cs = 0;
     462             245 :         int case_sensitive = CONST_CS;
     463                 :         zend_constant c;
     464                 :         char *p;
     465                 : 
     466             245 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &name, &name_len, &val, &non_cs) == FAILURE) {
     467               4 :                 return;
     468                 :         }
     469                 : 
     470             241 :         if(non_cs) {
     471             124 :                 case_sensitive = 0;
     472                 :         }
     473                 : 
     474                 :         /* class constant, check if there is name and make sure class is valid & exists */
     475             241 :         if ((p = zend_memnstr(name, "::", sizeof("::") - 1, name + name_len))) {
     476                 :                 char *class_name;
     477                 :                 int found;
     478                 :                 zend_class_entry **ce;
     479                 :                 ALLOCA_FLAG(use_heap)
     480                 : 
     481               1 :                 if (p == (name + name_len - sizeof("::") + 1)) {
     482               1 :                         zend_error(E_WARNING, "Class constant must have a name");
     483               1 :                         RETURN_FALSE;
     484               0 :                 } else if (p == name) {
     485               0 :                         zend_error(E_WARNING, "Missing class name");
     486               0 :                         RETURN_FALSE;
     487                 :                 }
     488                 : 
     489               0 :                 class_name = do_alloca_with_limit((p - name + 1), use_heap);
     490               0 :                 zend_str_tolower_copy(class_name, name, (p - name));
     491                 : 
     492               0 :                 found = zend_hash_find(EG(class_table), class_name, p - name + 1, (void **) &ce);
     493                 : 
     494               0 :                 if (found != SUCCESS) {
     495               0 :                         zend_error(E_WARNING, "Class '%s' does not exist", class_name);
     496               0 :                         free_alloca_with_limit(class_name, use_heap);
     497               0 :                         RETURN_FALSE;
     498                 :                 }
     499               0 :                 free_alloca_with_limit(class_name, use_heap);
     500                 :         }
     501                 : 
     502             240 : repeat:
     503             240 :         switch (Z_TYPE_P(val)) {
     504                 :                 case IS_LONG:
     505                 :                 case IS_DOUBLE:
     506                 :                 case IS_STRING:
     507                 :                 case IS_BOOL:
     508                 :                 case IS_RESOURCE:
     509                 :                 case IS_NULL:
     510             236 :                         break;
     511                 :                 case IS_OBJECT:
     512               3 :                         if (!val_free) {
     513               3 :                                 if (Z_OBJ_HT_P(val)->get) {
     514               0 :                                         val_free = val = Z_OBJ_HT_P(val)->get(val TSRMLS_CC);
     515               0 :                                         goto repeat;
     516               3 :                                 } else if (Z_OBJ_HT_P(val)->cast_object) {
     517               3 :                                         ALLOC_INIT_ZVAL(val_free);
     518               3 :                                         if (Z_OBJ_HT_P(val)->cast_object(val, val_free, IS_STRING TSRMLS_CC) == SUCCESS) {
     519               1 :                                                 val = val_free;
     520               1 :                                                 break;
     521                 :                                         }
     522                 :                                 }
     523                 :                         }
     524                 :                         /* no break */
     525                 :                 default:
     526               3 :                         zend_error(E_WARNING,"Constants may only evaluate to scalar values");
     527               3 :                         if (val_free) {
     528               2 :                                 zval_ptr_dtor(&val_free);
     529                 :                         }
     530               3 :                         RETURN_FALSE;
     531                 :         }
     532                 :         
     533             237 :         c.value = *val;
     534             237 :         zval_copy_ctor(&c.value);
     535             237 :         if (val_free) {
     536               1 :                 zval_ptr_dtor(&val_free);
     537                 :         }
     538             237 :         c.flags = case_sensitive; /* non persistent */
     539             237 :         c.name = zend_strndup(name, name_len);
     540             237 :         c.name_len = name_len+1;
     541             237 :         c.module_number = PHP_USER_CONSTANT;
     542             237 :         if (zend_register_constant(&c TSRMLS_CC) == SUCCESS) {
     543             233 :                 RETURN_TRUE;
     544                 :         } else {
     545               4 :                 RETURN_FALSE;
     546                 :         }
     547                 : }
     548                 : /* }}} */
     549                 : 
     550                 : 
     551                 : /* {{{ proto bool defined(string constant_name)
     552                 :    Check whether a constant exists */
     553                 : ZEND_FUNCTION(defined)
     554              81 : {
     555                 :         zval **var;
     556                 :         zval c;
     557                 : 
     558              81 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &var)==FAILURE) {
     559               0 :                 ZEND_WRONG_PARAM_COUNT();
     560                 :         }
     561                 :         
     562              81 :         convert_to_string_ex(var);
     563              81 :         if (zend_get_constant(Z_STRVAL_PP(var), Z_STRLEN_PP(var), &c TSRMLS_CC)) {
     564              74 :                 zval_dtor(&c);
     565              74 :                 RETURN_TRUE;
     566                 :         } else {
     567               7 :                 RETURN_FALSE;
     568                 :         }
     569                 : }
     570                 : /* }}} */
     571                 : 
     572                 : 
     573                 : /* {{{ proto string get_class([object object])
     574                 :    Retrieves the class name */
     575                 : ZEND_FUNCTION(get_class)
     576             294 : {
     577                 :         zval **arg;
     578             294 :         char *name = "";
     579             294 :         zend_uint name_len = 0;
     580                 :         int dup;
     581                 : 
     582             294 :         if (!ZEND_NUM_ARGS()) {
     583               5 :                 if (EG(scope)) {
     584               4 :                         RETURN_STRINGL(EG(scope)->name, EG(scope)->name_length, 1);
     585                 :                 } else {
     586               1 :                         zend_error(E_WARNING, "get_class() called without object from outside a class");
     587               1 :                         RETURN_FALSE;
     588                 :                 }
     589                 :         }
     590             289 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
     591               1 :                 ZEND_WRONG_PARAM_COUNT();
     592                 :         }
     593             288 :         if (Z_TYPE_PP(arg) != IS_OBJECT) {
     594              27 :                 RETURN_FALSE;
     595                 :         }
     596                 : 
     597             261 :         dup = zend_get_object_classname(*arg, &name, &name_len TSRMLS_CC);
     598                 : 
     599             261 :         RETURN_STRINGL(name, name_len, dup);
     600                 : }
     601                 : /* }}} */
     602                 : 
     603                 : 
     604                 : /* {{{ proto string get_parent_class([mixed object])
     605                 :    Retrieves the parent class name for object or class or current scope. */
     606                 : ZEND_FUNCTION(get_parent_class)
     607              47 : {
     608                 :         zval **arg;
     609              47 :         zend_class_entry *ce = NULL;
     610                 :         char *name;
     611                 :         zend_uint name_length;
     612                 :         
     613              47 :         if (!ZEND_NUM_ARGS()) {
     614               3 :                 ce = EG(scope);
     615               3 :                 if (ce && ce->parent) {
     616               1 :                         RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
     617                 :                 } else {
     618               2 :                         RETURN_FALSE;
     619                 :                 }
     620                 :         }
     621              44 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &arg)==FAILURE) {
     622               1 :                 ZEND_WRONG_PARAM_COUNT();
     623                 :         }
     624                 : 
     625              43 :         if (Z_TYPE_PP(arg) == IS_OBJECT) {
     626               7 :                 if (Z_OBJ_HT_PP(arg)->get_class_name
     627                 :                         && Z_OBJ_HT_PP(arg)->get_class_name(*arg, &name, &name_length, 1 TSRMLS_CC) == SUCCESS) {
     628               3 :                         RETURN_STRINGL(name, name_length, 0);
     629                 :                 } else {
     630               4 :                         ce = zend_get_class_entry(*arg TSRMLS_CC);
     631                 :                 }
     632              36 :         } else if (Z_TYPE_PP(arg) == IS_STRING) {
     633                 :                 zend_class_entry **pce;
     634                 :                 
     635              12 :                 if (zend_lookup_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &pce TSRMLS_CC) == SUCCESS) {
     636               5 :                         ce = *pce;
     637                 :                 }
     638                 :         }
     639                 : 
     640              40 :         if (ce && ce->parent) {
     641               2 :                 RETURN_STRINGL(ce->parent->name, ce->parent->name_length, 1);
     642                 :         } else {
     643              38 :                 RETURN_FALSE;
     644                 :         }
     645                 : }
     646                 : /* }}} */
     647                 : 
     648                 : 
     649                 : static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
     650             144 : {
     651                 :         zval **obj, **class_name;
     652                 :         zend_class_entry *instance_ce;
     653                 :         zend_class_entry **ce;
     654                 :         zend_bool retval;
     655                 : 
     656             144 :         if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &obj, &class_name)==FAILURE) {
     657               4 :                 ZEND_WRONG_PARAM_COUNT();
     658                 :         }
     659                 : 
     660             142 :         if (only_subclass && Z_TYPE_PP(obj) == IS_STRING) {
     661                 :                 zend_class_entry **the_ce;
     662              10 :                 if (zend_lookup_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), &the_ce TSRMLS_CC) == FAILURE) {
     663               8 :                         zend_error(E_WARNING, "Unknown class passed as parameter");
     664               8 :                         RETURN_FALSE;
     665                 :                 }
     666               2 :                 instance_ce = *the_ce;
     667             130 :         } else if (Z_TYPE_PP(obj) != IS_OBJECT) {
     668              70 :                 RETURN_FALSE;
     669                 :         } else {
     670              60 :                 instance_ce = NULL;
     671                 :         }
     672                 : 
     673                 :         /* TBI!! new object handlers */
     674              62 :         if (Z_TYPE_PP(obj) == IS_OBJECT && !HAS_CLASS_ENTRY(**obj)) {
     675               0 :                 RETURN_FALSE;
     676                 :         }
     677                 : 
     678              62 :         convert_to_string_ex(class_name);
     679                 : 
     680              62 :         if (zend_lookup_class_ex(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name), 0, &ce TSRMLS_CC) == FAILURE) {
     681              53 :                 retval = 0;
     682                 :         } else {
     683               9 :                 if (only_subclass) {
     684               5 :                         if (!instance_ce) {
     685               4 :                                 instance_ce = Z_OBJCE_PP(obj)->parent;
     686                 :                         } else {
     687               1 :                                 instance_ce = instance_ce->parent;
     688                 :                         }
     689                 :                 } else {
     690               4 :                         instance_ce = Z_OBJCE_PP(obj);
     691                 :                 }
     692                 : 
     693               9 :                 if (!instance_ce) {
     694               1 :                         RETURN_FALSE;
     695                 :                 }
     696                 : 
     697               8 :                 if (instanceof_function(instance_ce, *ce TSRMLS_CC)) {
     698               6 :                         retval = 1;
     699                 :                 } else {
     700               2 :                         retval = 0;
     701                 :                 }
     702                 :         }
     703                 : 
     704              61 :         RETURN_BOOL(retval);
     705                 : }
     706                 : 
     707                 : 
     708                 : /* {{{ proto bool is_subclass_of(object object, string class_name)
     709                 :    Returns true if the object has this class as one of its parents */
     710                 : ZEND_FUNCTION(is_subclass_of)
     711              86 : {
     712              86 :         is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     713              86 : }
     714                 : /* }}} */
     715                 : 
     716                 : 
     717                 : /* {{{ proto bool is_a(object object, string class_name)
     718                 :    Returns true if the object is of this class or has this class as one of its parents */
     719                 : ZEND_FUNCTION(is_a)
     720              58 : {
     721              58 :         zend_error(E_STRICT, "is_a(): Deprecated. Please use the instanceof operator");
     722              58 :         is_a_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     723              58 : }
     724                 : /* }}} */
     725                 : 
     726                 : 
     727                 : /* {{{ add_class_vars */
     728                 : static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *return_value TSRMLS_DC)
     729              64 : {
     730              64 :         if (zend_hash_num_elements(properties) > 0) {
     731                 :                 HashPosition pos;
     732                 :                 zval **prop;
     733                 : 
     734              45 :                 zend_hash_internal_pointer_reset_ex(properties, &pos);
     735             214 :                 while (zend_hash_get_current_data_ex(properties, (void **) &prop, &pos) == SUCCESS) {
     736                 :                         char *key, *class_name, *prop_name;
     737                 :                         uint key_len;
     738                 :                         ulong num_index;
     739             124 :                         int prop_name_len = 0;                  
     740                 :                         zval *prop_copy;
     741                 :                         zend_property_info *property_info;
     742                 :                         zval zprop_name;
     743                 : 
     744             124 :                         zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos);
     745             124 :                         zend_hash_move_forward_ex(properties, &pos);
     746                 : 
     747             124 :                         zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
     748             124 :                         prop_name_len = strlen(prop_name);
     749                 : 
     750             124 :                         ZVAL_STRINGL(&zprop_name, prop_name, prop_name_len, 0);
     751             124 :                         property_info = zend_get_property_info(ce, &zprop_name, 1 TSRMLS_CC);
     752                 : 
     753             124 :                         if (!property_info || property_info == &EG(std_property_info)) {
     754                 :                                 continue;
     755                 :                         }
     756                 : 
     757                 :                         /* copy: enforce read only access */
     758              78 :                         ALLOC_ZVAL(prop_copy);
     759              78 :                         *prop_copy = **prop;
     760              78 :                         zval_copy_ctor(prop_copy);
     761              78 :                         INIT_PZVAL(prop_copy);
     762                 : 
     763                 :                         /* this is necessary to make it able to work with default array 
     764                 :                         * properties, returned to user */
     765              78 :                         if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || Z_TYPE_P(prop_copy) == IS_CONSTANT) {
     766               0 :                                 zval_update_constant(&prop_copy, 0 TSRMLS_CC);
     767                 :                         }
     768                 : 
     769              78 :                         add_assoc_zval(return_value, prop_name, prop_copy);
     770                 :                 }
     771                 :         }
     772              64 : }
     773                 : /* }}} */
     774                 : 
     775                 : 
     776                 : /* {{{ proto array get_class_vars(string class_name)
     777                 :    Returns an array of default properties of the class. */
     778                 : ZEND_FUNCTION(get_class_vars)
     779              59 : {
     780                 :         char *class_name;
     781                 :         int class_name_len;
     782                 :         zend_class_entry **pce;
     783                 : 
     784              59 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &class_name, &class_name_len) == FAILURE) {
     785               7 :                 return;
     786                 :         }
     787                 : 
     788              52 :         if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC) == FAILURE) {
     789              20 :                 RETURN_FALSE;
     790                 :         } else {
     791              32 :                 array_init(return_value);
     792              32 :                 zend_update_class_constants(*pce TSRMLS_CC);
     793              32 :                 add_class_vars(*pce, &(*pce)->default_properties, return_value TSRMLS_CC);
     794              32 :                 add_class_vars(*pce, CE_STATIC_MEMBERS(*pce), return_value TSRMLS_CC);
     795                 :         }
     796                 : }
     797                 : /* }}} */
     798                 : 
     799                 : 
     800                 : /* {{{ proto array get_object_vars(object obj)
     801                 :    Returns an array of object properties */
     802                 : ZEND_FUNCTION(get_object_vars)
     803              61 : {
     804                 :         zval **obj;
     805                 :         zval **value;
     806                 :         HashTable *properties;
     807                 :         HashPosition pos;
     808                 :         char *key, *prop_name, *class_name;
     809                 :         uint key_len;
     810                 :         ulong num_index;
     811                 :         zend_object *zobj;
     812                 : 
     813              61 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &obj) == FAILURE) {
     814               2 :                 ZEND_WRONG_PARAM_COUNT();
     815                 :         }
     816                 : 
     817              59 :         if (Z_TYPE_PP(obj) != IS_OBJECT) {
     818              26 :                 RETURN_FALSE;
     819                 :         }
     820              33 :         if (Z_OBJ_HT_PP(obj)->get_properties == NULL) {
     821               0 :                 RETURN_FALSE;
     822                 :         }
     823                 : 
     824              33 :         properties = Z_OBJ_HT_PP(obj)->get_properties(*obj TSRMLS_CC);
     825                 : 
     826              33 :         if (properties == NULL) {
     827               0 :                 RETURN_FALSE;
     828                 :         }
     829                 : 
     830              33 :         zobj = zend_objects_get_address(*obj TSRMLS_CC);
     831                 : 
     832              33 :         array_init(return_value);
     833                 : 
     834              33 :         zend_hash_internal_pointer_reset_ex(properties, &pos);
     835                 : 
     836             189 :         while (zend_hash_get_current_data_ex(properties, (void **) &value, &pos) == SUCCESS) {
     837             123 :                 if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
     838             120 :                         if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) == SUCCESS) {
     839              92 :                                 zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
     840                 :                                 /* Not separating references */
     841              92 :                                 (*value)->refcount++;
     842              92 :                                 add_assoc_zval_ex(return_value, prop_name, strlen(prop_name)+1, *value);
     843                 :                         }
     844                 :                 }
     845             123 :                 zend_hash_move_forward_ex(properties, &pos);
     846                 :         }
     847                 : }
     848                 : /* }}} */
     849                 : 
     850                 : 
     851                 : /* {{{ proto array get_class_methods(mixed class)
     852                 :    Returns an array of method names for class or class instance. */
     853                 : ZEND_FUNCTION(get_class_methods)
     854              65 : {
     855                 :         zval **class;
     856                 :         zval *method_name;
     857              65 :         zend_class_entry *ce = NULL, **pce;
     858                 :         HashPosition pos;
     859                 :         zend_function *mptr;
     860                 : 
     861              65 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &class)==FAILURE) {
     862               2 :                 ZEND_WRONG_PARAM_COUNT();
     863                 :         }
     864                 : 
     865              63 :         if (Z_TYPE_PP(class) == IS_OBJECT) {
     866                 :                 /* TBI!! new object handlers */
     867               5 :                 if (!HAS_CLASS_ENTRY(**class)) {
     868               0 :                         RETURN_FALSE;
     869                 :                 }
     870               5 :                 ce = Z_OBJCE_PP(class);
     871              58 :         } else if (Z_TYPE_PP(class) == IS_STRING) {
     872              36 :                 if (zend_lookup_class(Z_STRVAL_PP(class), Z_STRLEN_PP(class), &pce TSRMLS_CC) == SUCCESS) {
     873              31 :                         ce = *pce;
     874                 :                 }
     875                 :         }
     876                 : 
     877              63 :         if (!ce) {
     878              27 :                 RETURN_NULL();
     879                 :         }
     880                 : 
     881              36 :         array_init(return_value);
     882              36 :         zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos);
     883                 : 
     884             217 :         while (zend_hash_get_current_data_ex(&ce->function_table, (void **) &mptr, &pos) == SUCCESS) {
     885             145 :                 if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC) 
     886                 :                  || (EG(scope) &&
     887                 :                      (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
     888                 :                        zend_check_protected(mptr->common.scope, EG(scope)))
     889                 :                    || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
     890                 :                        EG(scope) == mptr->common.scope)))) {
     891                 :                         char *key;
     892                 :                         uint key_len;
     893                 :                         ulong num_index;
     894             107 :                         uint len = strlen(mptr->common.function_name);
     895                 : 
     896                 :                         /* Do not display old-style inherited constructors */
     897             107 :                         if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 ||
     898                 :                             mptr->common.scope == ce ||
     899                 :                             zend_hash_get_current_key_ex(&ce->function_table, &key, &key_len, &num_index, 0, &pos) != HASH_KEY_IS_STRING ||
     900                 :                             zend_binary_strcasecmp(key, key_len-1, mptr->common.function_name, len) == 0) {
     901                 : 
     902             106 :                                 MAKE_STD_ZVAL(method_name);
     903             106 :                                 ZVAL_STRINGL(method_name, mptr->common.function_name, len, 1);
     904             106 :                                 zend_hash_next_index_insert(return_value->value.ht, &method_name, sizeof(zval *), NULL);
     905                 :                         }
     906                 :                 }
     907             145 :                 zend_hash_move_forward_ex(&ce->function_table, &pos);
     908                 :         }
     909                 : }
     910                 : /* }}} */
     911                 : 
     912                 : 
     913                 : /* {{{ proto bool method_exists(object object, string method)
     914                 :    Checks if the class method exists */
     915                 : ZEND_FUNCTION(method_exists)
     916             125 : {
     917                 :         zval **klass, **method_name;
     918                 :         char *lcname;
     919                 :         zend_class_entry * ce, **pce;
     920                 : 
     921             125 :         if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &klass, &method_name)==FAILURE) {
     922               2 :                 ZEND_WRONG_PARAM_COUNT();
     923                 :         }
     924             123 :         if (Z_TYPE_PP(klass) == IS_OBJECT) {
     925              71 :                 ce = Z_OBJCE_PP(klass);
     926              52 :         } else if (Z_TYPE_PP(klass) == IS_STRING) {
     927              30 :                 if (zend_lookup_class(Z_STRVAL_PP(klass), Z_STRLEN_PP(klass), &pce TSRMLS_CC) == FAILURE) {
     928               5 :                         RETURN_FALSE;
     929                 :                 }
     930              25 :                 ce = *pce;
     931                 :         } else {
     932              22 :                 RETURN_FALSE;
     933                 :         }
     934                 : 
     935              96 :         convert_to_string_ex(method_name);
     936              96 :         lcname = zend_str_tolower_dup(Z_STRVAL_PP(method_name), Z_STRLEN_PP(method_name));
     937              96 :         if (zend_hash_exists(&ce->function_table, lcname, Z_STRLEN_PP(method_name)+1)) {
     938              59 :                 efree(lcname);
     939              59 :                 RETURN_TRUE;
     940                 :         } else {
     941              37 :                 union _zend_function *func = NULL;
     942              37 :                 efree(lcname);
     943                 : 
     944              37 :                 if (Z_TYPE_PP(klass) == IS_OBJECT 
     945                 :                 && Z_OBJ_HT_PP(klass)->get_method != NULL
     946                 :                 && (func = Z_OBJ_HT_PP(klass)->get_method(klass, Z_STRVAL_PP(method_name), Z_STRLEN_PP(method_name) TSRMLS_CC)) != NULL
     947                 :                 ) {
     948               2 :                         if (func->type == ZEND_INTERNAL_FUNCTION 
     949                 :                         && ((zend_internal_function*)func)->handler == zend_std_call_user_call
     950                 :                         ) {
     951               2 :                                 efree(((zend_internal_function*)func)->function_name);
     952               2 :                                 efree(func);
     953               2 :                                 RETURN_FALSE;
     954                 :                         }
     955               0 :                         RETURN_TRUE;
     956                 :                 }
     957                 :         }
     958              35 :         RETURN_FALSE;
     959                 : }
     960                 : /* }}} */
     961                 : 
     962                 : /* {{{ proto bool property_exists(mixed object_or_class, string property_name)
     963                 :    Checks if the object or class has a property */
     964                 : ZEND_FUNCTION(property_exists)
     965              98 : {
     966                 :         zval **object, **property;
     967                 :         zend_class_entry *ce, **pce;
     968                 :         zend_property_info *property_info;
     969                 :         char *prop_name, *class_name;
     970                 : 
     971              98 :         if (ZEND_NUM_ARGS()!= 2 || zend_get_parameters_ex(2, &object, &property)==FAILURE) {
     972               4 :                 ZEND_WRONG_PARAM_COUNT();
     973                 :         }
     974              94 :         convert_to_string_ex(property);
     975              94 :         if (!Z_STRLEN_PP(property)) {
     976               6 :                 RETURN_FALSE;
     977                 :         }
     978                 : 
     979              88 :         switch((*object)->type) {
     980                 :         case IS_STRING:
     981              54 :                 if (!Z_STRLEN_PP(object)) {
     982               1 :                         RETURN_FALSE;
     983                 :                 }
     984              53 :                 if (zend_lookup_class(Z_STRVAL_PP(object), Z_STRLEN_PP(object), &pce TSRMLS_CC) == SUCCESS) {
     985              52 :                         ce = *pce;
     986                 :                 } else {
     987               1 :                         RETURN_FALSE;
     988                 :                 }
     989              52 :                 if (!ce) {
     990               0 :                         RETURN_NULL();
     991                 :                 }
     992              52 :                 if (!(property_info = zend_get_property_info(ce, *property, 1 TSRMLS_CC)) || property_info == &EG(std_property_info)) {
     993              27 :                         RETURN_FALSE;
     994                 :                 }
     995              25 :                 if (property_info->flags & ZEND_ACC_PUBLIC) {
     996              14 :                         RETURN_TRUE;
     997                 :                 }
     998              11 :                 zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name);
     999              11 :                 if (!strncmp(class_name, "*", 1)) {
    1000               7 :                         if (instanceof_function(EG(scope), ce TSRMLS_CC) ||
    1001                 :                                 (EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC))) {
    1002               6 :                                 RETURN_TRUE;
    1003                 :                         }
    1004               1 :                         RETURN_FALSE;
    1005                 :                 }
    1006               4 :                 if (zend_lookup_class(Z_STRVAL_PP(object), Z_STRLEN_PP(object), &pce TSRMLS_CC) == SUCCESS) {
    1007               4 :                         ce = *pce;
    1008                 :                 } else {
    1009               0 :                         RETURN_FALSE; /* shouldn't happen */
    1010                 :                 }
    1011               4 :                 RETURN_BOOL(EG(scope) == ce);
    1012                 : 
    1013                 :         case IS_OBJECT:
    1014              28 :                 if (Z_OBJ_HANDLER_PP(object, has_property) && Z_OBJ_HANDLER_PP(object, has_property)(*object, *property, 2 TSRMLS_CC)) {
    1015              13 :                         RETURN_TRUE;
    1016                 :                 }
    1017              15 :                 RETURN_FALSE;
    1018                 : 
    1019                 :         default:
    1020               6 :                 zend_error(E_WARNING, "First parameter must either be an object or the name of an existing class");
    1021               6 :                 RETURN_NULL();
    1022                 :         }
    1023                 : }
    1024                 : /* }}} */
    1025                 : 
    1026                 : 
    1027                 : /* {{{ proto bool class_exists(string classname [, bool autoload])
    1028                 :    Checks if the class exists */
    1029                 : ZEND_FUNCTION(class_exists)
    1030             264 : {
    1031                 :         char *class_name, *lc_name;
    1032                 :         zend_class_entry **ce;
    1033                 :         int class_name_len;
    1034                 :         int found;
    1035             264 :         zend_bool autoload = 1;
    1036                 :         ALLOCA_FLAG(use_heap)
    1037                 : 
    1038             264 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &class_name, &class_name_len, &autoload) == FAILURE) {
    1039              16 :                 return;
    1040                 :         }
    1041                 : 
    1042             248 :         if (!autoload) {
    1043              51 :                 lc_name = do_alloca_with_limit(class_name_len + 1, use_heap);
    1044              51 :                 zend_str_tolower_copy(lc_name, class_name, class_name_len);
    1045                 :         
    1046              51 :                 found = zend_hash_find(EG(class_table), lc_name, class_name_len+1, (void **) &ce);
    1047              51 :                 free_alloca_with_limit(lc_name, use_heap);
    1048              51 :                 RETURN_BOOL(found == SUCCESS && !((*ce)->ce_flags & ZEND_ACC_INTERFACE));
    1049                 :         }
    1050                 : 
    1051             197 :         if (zend_lookup_class(class_name, class_name_len, &ce TSRMLS_CC) == SUCCESS) {
    1052             132 :                 RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) == 0);
    1053                 :         } else {
    1054              65 :                 RETURN_FALSE;
    1055                 :         }
    1056                 : }
    1057                 : /* }}} */
    1058                 : 
    1059                 : /* {{{ proto bool interface_exists(string classname [, bool autoload])
    1060                 :    Checks if the class exists */
    1061                 : ZEND_FUNCTION(interface_exists)
    1062              93 : {
    1063                 :         char *iface_name, *lc_name;
    1064                 :         zend_class_entry **ce;
    1065                 :         int iface_name_len;
    1066                 :         int found;
    1067              93 :         zend_bool autoload = 1;
    1068                 :         ALLOCA_FLAG(use_heap)
    1069                 : 
    1070              93 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &iface_name, &iface_name_len, &autoload) == FAILURE) {
    1071              15 :                 return;
    1072                 :         }
    1073                 : 
    1074              78 :         if (!autoload) {
    1075              17 :                 lc_name = do_alloca_with_limit(iface_name_len + 1, use_heap);
    1076              17 :                 zend_str_tolower_copy(lc_name, iface_name, iface_name_len);
    1077                 :         
    1078              17 :                 found = zend_hash_find(EG(class_table), lc_name, iface_name_len+1, (void **) &ce);
    1079              17 :                 free_alloca_with_limit(lc_name, use_heap);
    1080              17 :                 RETURN_BOOL(found == SUCCESS && (*ce)->ce_flags & ZEND_ACC_INTERFACE);
    1081                 :         }
    1082                 : 
    1083              61 :         if (zend_lookup_class(iface_name, iface_name_len, &ce TSRMLS_CC) == SUCCESS) {
    1084              25 :                 RETURN_BOOL(((*ce)->ce_flags & ZEND_ACC_INTERFACE) > 0);
    1085                 :         } else {
    1086              36 :                 RETURN_FALSE;
    1087                 :         }
    1088                 : }
    1089                 : /* }}} */
    1090                 : 
    1091                 : 
    1092                 : /* {{{ proto bool function_exists(string function_name) 
    1093                 :    Checks if the function exists */
    1094                 : ZEND_FUNCTION(function_exists)
    1095            1580 : {
    1096                 :         zval **function_name;
    1097                 :         zend_function *func;
    1098                 :         char *lcname;
    1099                 :         zend_bool retval;
    1100                 :         
    1101            1580 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) {
    1102               2 :                 ZEND_WRONG_PARAM_COUNT();
    1103                 :         }
    1104            1578 :         convert_to_string_ex(function_name);
    1105            1578 :         lcname = zend_str_tolower_dup(Z_STRVAL_PP(function_name), Z_STRLEN_PP(function_name));
    1106                 : 
    1107            1578 :         retval = (zend_hash_find(EG(function_table), lcname, Z_STRLEN_PP(function_name)+1, (void **)&func) == SUCCESS);
    1108                 :         
    1109            1578 :         efree(lcname);
    1110                 : 
    1111                 :         /*
    1112                 :          * A bit of a hack, but not a bad one: we see if the handler of the function
    1113                 :          * is actually one that displays "function is disabled" message.
    1114                 :          */
    1115            1578 :         if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
    1116                 :                 func->internal_function.handler == zif_display_disabled_function) {
    1117               0 :                 retval = 0;
    1118                 :         }
    1119                 : 
    1120            1578 :         RETURN_BOOL(retval);
    1121                 : }
    1122                 : /* }}} */
    1123                 : 
    1124                 : #if ZEND_DEBUG
    1125                 : /* {{{ proto void leak(int num_bytes=3)
    1126                 :    Cause an intentional memory leak, for testing/debugging purposes */
    1127                 : ZEND_FUNCTION(leak)
    1128                 : {
    1129                 :         int leakbytes=3;
    1130                 :         zval **leak;
    1131                 : 
    1132                 :         if (ZEND_NUM_ARGS()>=1) {
    1133                 :                 if (zend_get_parameters_ex(1, &leak)==SUCCESS) {
    1134                 :                         convert_to_long_ex(leak);
    1135                 :                         leakbytes = Z_LVAL_PP(leak);
    1136                 :                 }
    1137                 :         }
    1138                 : 
    1139                 :         emalloc(leakbytes);
    1140                 : }
    1141                 : /* }}} */
    1142                 : 
    1143                 : 
    1144                 : #ifdef ZEND_TEST_EXCEPTIONS
    1145                 : ZEND_FUNCTION(crash)
    1146                 : {
    1147                 :         char *nowhere=NULL;
    1148                 : 
    1149                 :         memcpy(nowhere, "something", sizeof("something"));
    1150                 : }
    1151                 : #endif
    1152                 : 
    1153                 : #endif /* ZEND_DEBUG */
    1154                 : 
    1155                 : /* {{{ proto array get_included_files(void)
    1156                 :    Returns an array with the file names that were include_once()'d */
    1157                 : ZEND_FUNCTION(get_included_files)
    1158              11 : {
    1159                 :         char *entry;
    1160              11 :         if (ZEND_NUM_ARGS() != 0) {
    1161               3 :                 ZEND_WRONG_PARAM_COUNT();
    1162                 :         }
    1163                 : 
    1164               8 :         array_init(return_value);
    1165               8 :         zend_hash_internal_pointer_reset(&EG(included_files));
    1166              31 :         while (zend_hash_get_current_key(&EG(included_files), &entry, NULL, 1) == HASH_KEY_IS_STRING) {
    1167              15 :                 add_next_index_string(return_value, entry, 0);
    1168              15 :                 zend_hash_move_forward(&EG(included_files));
    1169                 :         }
    1170                 : }
    1171                 : /* }}} */
    1172                 : 
    1173                 : 
    1174                 : /* {{{ proto void trigger_error(string messsage [, int error_type])
    1175                 :    Generates a user-level error/warning/notice message */
    1176                 : ZEND_FUNCTION(trigger_error)
    1177              10 : {
    1178              10 :         int error_type = E_USER_NOTICE;
    1179                 :         zval **z_error_type, **z_error_message;
    1180                 : 
    1181              10 :         switch (ZEND_NUM_ARGS()) {
    1182                 :                 case 1:
    1183               3 :                         if (zend_get_parameters_ex(1, &z_error_message)==FAILURE) {
    1184               0 :                                 ZEND_WRONG_PARAM_COUNT();
    1185                 :                         }
    1186               3 :                         break;
    1187                 :                 case 2:
    1188               6 :                         if (zend_get_parameters_ex(2, &z_error_message, &z_error_type)==FAILURE) {
    1189               0 :                                 ZEND_WRONG_PARAM_COUNT();
    1190                 :                         }
    1191               6 :                         convert_to_long_ex(z_error_type);
    1192               6 :                         error_type = Z_LVAL_PP(z_error_type);
    1193               6 :                         switch (error_type) {
    1194                 :                                 case E_USER_ERROR:
    1195                 :                                 case E_USER_WARNING:
    1196                 :                                 case E_USER_NOTICE:
    1197                 :                                         break;
    1198                 :                                 default:
    1199               2 :                                         zend_error(E_WARNING, "Invalid error type specified");
    1200               2 :                                         RETURN_FALSE;
    1201                 :                                         break;
    1202                 :                         }
    1203               4 :                         break;
    1204                 :                 default:
    1205               1 :                         ZEND_WRONG_PARAM_COUNT();       
    1206                 :         }
    1207               7 :         convert_to_string_ex(z_error_message);
    1208               7 :         zend_error(error_type, "%s", Z_STRVAL_PP(z_error_message));
    1209               6 :         RETURN_TRUE;
    1210                 : }
    1211                 : /* }}} */
    1212                 : 
    1213                 : 
    1214                 : /* {{{ proto string set_error_handler(string error_handler [, int error_types])
    1215                 :    Sets a user-defined error handler function.  Returns the previously defined error handler, or false on error */
    1216                 : ZEND_FUNCTION(set_error_handler)
    1217             214 : {
    1218                 :         zval *error_handler;
    1219             214 :         zend_bool had_orig_error_handler=0;
    1220             214 :         char *error_handler_name = NULL;
    1221             214 :         long error_type = E_ALL | E_STRICT;
    1222                 : 
    1223             214 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &error_handler, &error_type) == FAILURE) {
    1224               0 :                 return;
    1225                 :         }
    1226                 : 
    1227             214 :         if (!zend_is_callable(error_handler, 0, &error_handler_name)) {
    1228               0 :                 zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
    1229                 :                                    get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
    1230               0 :                 efree(error_handler_name);
    1231               0 :                 return;
    1232                 :         }
    1233             214 :         efree(error_handler_name);
    1234                 : 
    1235             214 :         if (EG(user_error_handler)) {
    1236               0 :                 had_orig_error_handler = 1;
    1237               0 :                 *return_value = *EG(user_error_handler);
    1238               0 :                 zval_copy_ctor(return_value);
    1239               0 :                 INIT_PZVAL(return_value);
    1240               0 :                 zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
    1241               0 :                 zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
    1242                 :         }
    1243             214 :         ALLOC_ZVAL(EG(user_error_handler));
    1244                 : 
    1245             214 :         if (!zend_is_true(error_handler)) { /* unset user-defined handler */
    1246               0 :                 FREE_ZVAL(EG(user_error_handler));
    1247               0 :                 EG(user_error_handler) = NULL;
    1248               0 :                 RETURN_TRUE;
    1249                 :         }
    1250                 : 
    1251             214 :         EG(user_error_handler_error_reporting) = (int)error_type;
    1252             214 :         *EG(user_error_handler) = *error_handler;
    1253             214 :         zval_copy_ctor(EG(user_error_handler));
    1254             214 :         INIT_PZVAL(EG(user_error_handler));
    1255                 : 
    1256             214 :         if (!had_orig_error_handler) {
    1257             214 :                 RETURN_NULL();
    1258                 :         }
    1259                 : }
    1260                 : /* }}} */
    1261                 : 
    1262                 : 
    1263                 : /* {{{ proto void restore_error_handler(void)
    1264                 :    Restores the previously defined error handler function */
    1265                 : ZEND_FUNCTION(restore_error_handler)
    1266               1 : {
    1267               1 :         if (EG(user_error_handler)) {
    1268               1 :                 zval *zeh = EG(user_error_handler);
    1269                 : 
    1270               1 :                 EG(user_error_handler) = NULL;
    1271               1 :                 zval_ptr_dtor(&zeh);
    1272                 :         }
    1273                 : 
    1274               1 :         if (zend_ptr_stack_num_elements(&EG(user_error_handlers))==0) {
    1275               1 :                 EG(user_error_handler) = NULL;
    1276                 :         } else {
    1277               0 :                 EG(user_error_handler_error_reporting) = zend_stack_int_top(&EG(user_error_handlers_error_reporting));
    1278               0 :                 zend_stack_del_top(&EG(user_error_handlers_error_reporting));
    1279               0 :                 EG(user_error_handler) = zend_ptr_stack_pop(&EG(user_error_handlers));
    1280                 :         }
    1281               1 :         RETURN_TRUE;
    1282                 : }
    1283                 : /* }}} */
    1284                 : 
    1285                 : 
    1286                 : /* {{{ proto string set_exception_handler(callable exception_handler)
    1287                 :    Sets a user-defined exception handler function.  Returns the previously defined exception handler, or false on error */
    1288                 : ZEND_FUNCTION(set_exception_handler)
    1289              14 : {
    1290                 :         zval **exception_handler;
    1291              14 :         char *exception_handler_name = NULL;
    1292              14 :         zend_bool had_orig_exception_handler=0;
    1293                 : 
    1294              14 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &exception_handler)==FAILURE) {
    1295               2 :                 ZEND_WRONG_PARAM_COUNT();
    1296                 :         }
    1297                 : 
    1298              12 :         if (Z_TYPE_PP(exception_handler) != IS_NULL) { /* NULL == unset */
    1299              12 :                 if (!zend_is_callable(*exception_handler, 0, &exception_handler_name)) {
    1300               2 :                         zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
    1301                 :                                            get_active_function_name(TSRMLS_C), exception_handler_name?exception_handler_name:"unknown");
    1302               2 :                         efree(exception_handler_name);
    1303               2 :                         return;
    1304                 :                 }
    1305              10 :                 efree(exception_handler_name);
    1306                 :         }
    1307                 : 
    1308              10 :         if (EG(user_exception_handler)) {
    1309               2 :                 had_orig_exception_handler = 1;
    1310               2 :                 *return_value = *EG(user_exception_handler);
    1311               2 :                 zval_copy_ctor(return_value);
    1312               2 :                 zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler));
    1313                 :         }
    1314              10 :         ALLOC_ZVAL(EG(user_exception_handler));
    1315                 : 
    1316              10 :         if (Z_TYPE_PP(exception_handler) == IS_NULL) { /* unset user-defined handler */
    1317               0 :                 FREE_ZVAL(EG(user_exception_handler));
    1318               0 :                 EG(user_exception_handler) = NULL;
    1319               0 :                 RETURN_TRUE;
    1320                 :         }
    1321                 : 
    1322              10 :         *EG(user_exception_handler) = **exception_handler;
    1323              10 :         zval_copy_ctor(EG(user_exception_handler));
    1324                 : 
    1325              10 :         if (!had_orig_exception_handler) {
    1326               8 :                 RETURN_NULL();
    1327                 :         }
    1328                 : }
    1329                 : /* }}} */
    1330                 : 
    1331                 : 
    1332                 : /* {{{ proto void restore_exception_handler(void)
    1333                 :    Restores the previously defined exception handler function */
    1334                 : ZEND_FUNCTION(restore_exception_handler)
    1335               1 : {
    1336               1 :         if (EG(user_exception_handler)) {
    1337               1 :                 zval_ptr_dtor(&EG(user_exception_handler));
    1338                 :         }
    1339               1 :         if (zend_ptr_stack_num_elements(&EG(user_exception_handlers))==0) {
    1340               0 :                 EG(user_exception_handler) = NULL;
    1341                 :         } else {
    1342               1 :                 EG(user_exception_handler) = zend_ptr_stack_pop(&EG(user_exception_handlers));
    1343                 :         }
    1344               1 :         RETURN_TRUE;
    1345                 : }
    1346                 : /* }}} */
    1347                 : 
    1348                 : 
    1349                 : static int copy_class_or_interface_name(zend_class_entry **pce, int num_args, va_list args, zend_hash_key *hash_key)
    1350            1942 : {
    1351            1942 :         zval *array = va_arg(args, zval *);
    1352            1942 :         zend_uint mask = va_arg(args, zend_uint);
    1353            1942 :         zend_uint comply = va_arg(args, zend_uint);
    1354            1942 :         zend_uint comply_mask = (comply)? mask:0;
    1355            1942 :         zend_class_entry *ce  = *pce;
    1356                 : 
    1357            1942 :         if ((hash_key->nKeyLength==0 || hash_key->arKey[0]!=0)
    1358                 :                 && (comply_mask == (ce->ce_flags & mask))) {
    1359             919 :                 add_next_index_stringl(array, ce->name, ce->name_length, 1);
    1360                 :         }
    1361            1942 :         return ZEND_HASH_APPLY_KEEP;
    1362                 : }
    1363                 : 
    1364                 : 
    1365                 : /* {{{ proto array get_declared_classes()
    1366                 :    Returns an array of all declared classes. */
    1367                 : ZEND_FUNCTION(get_declared_classes)
    1368               8 : {
    1369               8 :         zend_uint mask = ZEND_ACC_INTERFACE;
    1370               8 :         zend_uint comply = 0;
    1371                 : 
    1372               8 :         if (ZEND_NUM_ARGS() != 0) {
    1373               1 :                 ZEND_WRONG_PARAM_COUNT();
    1374                 :         }
    1375                 : 
    1376               7 :         array_init(return_value);
    1377               7 :         zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
    1378                 : }
    1379                 : /* }}} */
    1380                 : 
    1381                 : /* {{{ proto array get_declared_interfaces()
    1382                 :    Returns an array of all declared interfaces. */
    1383                 : ZEND_FUNCTION(get_declared_interfaces)
    1384              10 : {
    1385              10 :         zend_uint mask = ZEND_ACC_INTERFACE;
    1386              10 :         zend_uint comply = 1;
    1387                 : 
    1388              10 :         if (ZEND_NUM_ARGS() != 0) {
    1389               2 :                 ZEND_WRONG_PARAM_COUNT();
    1390                 :         }
    1391                 : 
    1392               8 :         array_init(return_value);
    1393               8 :         zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) copy_class_or_interface_name, 3, return_value, mask, comply);
    1394                 : }
    1395                 : /* }}} */
    1396                 : 
    1397                 : 
    1398                 : static int copy_function_name(zend_function *func, int num_args, va_list args, zend_hash_key *hash_key)
    1399            8285 : {
    1400            8285 :         zval *internal_ar = va_arg(args, zval *),
    1401            8285 :              *user_ar     = va_arg(args, zval *);
    1402                 : 
    1403            8285 :         if (hash_key->nKeyLength == 0 || hash_key->arKey[0] == 0) {
    1404               0 :                 return 0;
    1405                 :         }
    1406                 : 
    1407            8285 :         if (func->type == ZEND_INTERNAL_FUNCTION) {
    1408            8276 :                 add_next_index_stringl(internal_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
    1409               9 :         } else if (func->type == ZEND_USER_FUNCTION) {
    1410               9 :                 add_next_index_stringl(user_ar, hash_key->arKey, hash_key->nKeyLength-1, 1);
    1411                 :         }
    1412                 : 
    1413            8285 :         return 0;
    1414                 : }
    1415                 : 
    1416                 : 
    1417                 : /* {{{ proto array get_defined_functions(void)
    1418                 :    Returns an array of all defined functions */
    1419                 : ZEND_FUNCTION(get_defined_functions)
    1420               6 : {
    1421                 :         zval *internal;
    1422                 :         zval *user;
    1423                 : 
    1424               6 :         if (ZEND_NUM_ARGS() != 0) {
    1425               2 :                 ZEND_WRONG_PARAM_COUNT();
    1426                 :         }
    1427                 : 
    1428               4 :         MAKE_STD_ZVAL(internal);
    1429               4 :         MAKE_STD_ZVAL(user);
    1430                 : 
    1431               4 :         array_init(internal);
    1432               4 :         array_init(user);
    1433               4 :         array_init(return_value);
    1434                 : 
    1435               4 :         zend_hash_apply_with_arguments(EG(function_table), (apply_func_args_t) copy_function_name, 2, internal, user);
    1436                 : 
    1437               4 :         if (zend_hash_add(Z_ARRVAL_P(return_value), "internal", sizeof("internal"), (void **)&internal, sizeof(zval *), NULL) == FAILURE) {
    1438               0 :                 zval_ptr_dtor(&internal);
    1439               0 :                 zval_ptr_dtor(&user);
    1440               0 :                 zval_dtor(return_value);
    1441               0 :                 zend_error(E_WARNING, "Cannot add internal functions to return value from get_defined_functions()");
    1442               0 :                 RETURN_FALSE;
    1443                 :         }
    1444                 : 
    1445               4 :         if (zend_hash_add(Z_ARRVAL_P(return_value), "user", sizeof("user"), (void **)&user, sizeof(zval *), NULL) == FAILURE) {
    1446               0 :                 zval_ptr_dtor(&user);
    1447               0 :                 zval_dtor(return_value);
    1448               0 :                 zend_error(E_WARNING, "Cannot add user functions to return value from get_defined_functions()");
    1449               0 :                 RETURN_FALSE;
    1450                 :         }
    1451                 : }
    1452                 : /* }}} */
    1453                 : 
    1454                 : 
    1455                 : /* {{{ proto array get_defined_vars(void)
    1456                 :    Returns an associative array of names and values of all currently defined variable names (variables in the current scope) */
    1457                 : ZEND_FUNCTION(get_defined_vars)
    1458              17 : {
    1459                 :         zval *tmp;
    1460                 : 
    1461              17 :         array_init(return_value);
    1462                 : 
    1463              17 :         zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table),
    1464                 :                                         (copy_ctor_func_t)zval_add_ref, &tmp, sizeof(zval *));
    1465              17 : }
    1466                 : /* }}} */
    1467                 : 
    1468                 : 
    1469                 : #define LAMBDA_TEMP_FUNCNAME    "__lambda_func"
    1470                 : /* {{{ proto string create_function(string args, string code)
    1471                 :    Creates an anonymous function, and returns its name (funny, eh?) */
    1472                 : ZEND_FUNCTION(create_function)
    1473              42 : {
    1474                 :         char *eval_code, *function_name;
    1475                 :         int eval_code_length, function_name_length;
    1476                 :         zval **z_function_args, **z_function_code;
    1477                 :         int retval;
    1478                 :         char *eval_name;
    1479                 : 
    1480              42 :         if (ZEND_NUM_ARGS()!=2 || zend_get_parameters_ex(2, &z_function_args, &z_function_code)==FAILURE) {
    1481               0 :                 ZEND_WRONG_PARAM_COUNT();
    1482                 :         }
    1483                 : 
    1484              42 :         convert_to_string_ex(z_function_args);
    1485              42 :         convert_to_string_ex(z_function_code);
    1486                 : 
    1487              42 :         eval_code_length = sizeof("function " LAMBDA_TEMP_FUNCNAME)
    1488                 :                         +Z_STRLEN_PP(z_function_args)
    1489                 :                         +2      /* for the args parentheses */
    1490                 :                         +2      /* for the curly braces */
    1491                 :                         +Z_STRLEN_PP(z_function_code);
    1492                 : 
    1493              42 :         zend_spprintf(&eval_code, 0, "function " LAMBDA_TEMP_FUNCNAME "(%s){%s}", Z_STRVAL_PP(z_function_args), Z_STRVAL_PP(z_function_code));
    1494                 : 
    1495              42 :         eval_name = zend_make_compiled_string_description("runtime-created function" TSRMLS_CC);
    1496              42 :         retval = zend_eval_string(eval_code, NULL, eval_name TSRMLS_CC);
    1497              42 :         efree(eval_code);
    1498              42 :         efree(eval_name);
    1499                 : 
    1500              42 :         if (retval==SUCCESS) {
    1501                 :                 zend_function new_function, *func;
    1502                 : 
    1503              40 :                 if (zend_hash_find(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME), (void **) &func)==FAILURE) {
    1504               0 :                         zend_error(E_ERROR, "Unexpected inconsistency in create_function()");
    1505               0 :                         RETURN_FALSE;
    1506                 :                 }
    1507              40 :                 new_function = *func;
    1508              40 :                 function_add_ref(&new_function);
    1509                 : 
    1510              40 :                 function_name = (char *) emalloc(sizeof("0lambda_")+MAX_LENGTH_OF_LONG);
    1511                 : 
    1512                 :                 do {
    1513              40 :                         sprintf(function_name, "%clambda_%d", 0, ++EG(lambda_count));
    1514              40 :                         function_name_length = strlen(function_name+1)+1;
    1515              40 :                 } while (zend_hash_add(EG(function_table), function_name, function_name_length+1, &new_function, sizeof(zend_function), NULL)==FAILURE);
    1516              40 :                 zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
    1517              40 :                 RETURN_STRINGL(function_name, function_name_length, 0);
    1518                 :         } else {
    1519               2 :                 zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME));
    1520               2 :                 RETURN_FALSE;
    1521                 :         }
    1522                 : }
    1523                 : /* }}} */
    1524                 : 
    1525                 : 
    1526                 : #if ZEND_DEBUG
    1527                 : ZEND_FUNCTION(zend_test_func)
    1528                 : {
    1529                 :         zval *arg1, *arg2;
    1530                 : 
    1531                 :         zend_get_parameters(ht, 2, &arg1, &arg2);
    1532                 : }
    1533                 : 
    1534                 : 
    1535                 : #ifdef ZTS
    1536                 : ZEND_FUNCTION(zend_thread_id)
    1537                 : {
    1538                 :         RETURN_LONG(tsrm_thread_id());
    1539                 : }
    1540                 : #endif
    1541                 : #endif
    1542                 : 
    1543                 : /* {{{ proto string get_resource_type(resource res)
    1544                 :    Get the resource type name for a given resource */
    1545                 : ZEND_FUNCTION(get_resource_type)
    1546              74 : {
    1547                 :         char *resource_type;
    1548                 :         zval **z_resource_type;
    1549                 : 
    1550              74 :         if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &z_resource_type)==FAILURE) {
    1551               3 :                 ZEND_WRONG_PARAM_COUNT();
    1552                 :         }
    1553                 : 
    1554              71 :         if (Z_TYPE_PP(z_resource_type) != IS_RESOURCE) {
    1555               8 :                 zend_error(E_WARNING, "Supplied argument is not a valid resource handle");
    1556               8 :                 RETURN_FALSE;
    1557                 :         }
    1558                 : 
    1559              63 :         resource_type = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(z_resource_type) TSRMLS_CC);
    1560              63 :         if (resource_type) {
    1561              38 :                 RETURN_STRING(resource_type, 1);
    1562                 :         } else {
    1563              25 :                 RETURN_STRING("Unknown", 1);
    1564                 :         }
    1565                 : }
    1566                 : /* }}} */
    1567                 : 
    1568                 : 
    1569                 : static int add_extension_info(zend_module_entry *module, void *arg TSRMLS_DC)
    1570             240 : {
    1571             240 :         zval *name_array = (zval *)arg;
    1572             240 :         add_next_index_string(name_array, module->name, 1);
    1573             240 :         return 0;
    1574                 : }
    1575                 : 
    1576                 : static int add_zendext_info(zend_extension *ext, void *arg TSRMLS_DC)
    1577               0 : {
    1578               0 :         zval *name_array = (zval *)arg;
    1579               0 :         add_next_index_string(name_array, ext->name, 1);
    1580               0 :         return 0;
    1581                 : }
    1582                 : 
    1583                 : static int add_constant_info(zend_constant *constant, void *arg TSRMLS_DC)
    1584           15451 : {
    1585           15451 :         zval *name_array = (zval *)arg;
    1586                 :         zval *const_val;
    1587                 : 
    1588           15451 :         MAKE_STD_ZVAL(const_val);
    1589           15451 :         *const_val = constant->value;
    1590           15451 :         zval_copy_ctor(const_val);
    1591           15451 :         INIT_PZVAL(const_val);
    1592           15451 :         add_assoc_zval_ex(name_array, constant->name, constant->name_len, const_val);
    1593           15451 :         return 0;
    1594                 : }
    1595                 : 
    1596                 : 
    1597                 : /* {{{ proto array get_loaded_extensions([bool zend_extensions]) U
    1598                 :    Return an array containing names of loaded extensions */
    1599                 : ZEND_FUNCTION(get_loaded_extensions)
    1600               8 : {
    1601               8 :         zend_bool zendext = 0;
    1602                 : 
    1603               8 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &zendext) == FAILURE) {
    1604               2 :                 return;
    1605                 :         }
    1606                 : 
    1607               6 :         array_init(return_value);
    1608                 : 
    1609               6 :         if (zendext) {
    1610               2 :                 zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) add_zendext_info, return_value TSRMLS_CC);
    1611                 :         } else {
    1612               4 :                 zend_hash_apply_with_argument(&module_registry, (apply_func_arg_t) add_extension_info, return_value TSRMLS_CC);
    1613                 :         }
    1614                 : }
    1615                 : /* }}} */
    1616                 : 
    1617                 : 
    1618                 : /* {{{ proto array get_defined_constants([mixed categorize])
    1619                 :    Return an array containing the names and values of all defined constants */
    1620                 : ZEND_FUNCTION(get_defined_constants)
    1621              12 : {
    1622              12 :         zend_bool categorize = 0;
    1623                 : 
    1624              12 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &categorize) == FAILURE) {
    1625               2 :                 return;
    1626                 :         }
    1627                 : 
    1628              10 :         array_init(return_value);
    1629                 : 
    1630              10 :         if (categorize) {
    1631                 :                 HashPosition pos;
    1632                 :                 zend_constant *val;
    1633                 :                 int module_number;
    1634                 :                 zval **modules;
    1635                 :                 char **module_names;
    1636                 :                 zend_module_entry *module;
    1637               2 :                 int i = 1;
    1638                 : 
    1639               2 :                 modules = ecalloc(zend_hash_num_elements(&module_registry) + 2, sizeof(zval *));
    1640               2 :                 module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *));
    1641                 : 
    1642               2 :                 module_names[0] = "internal";
    1643               2 :                 zend_hash_internal_pointer_reset_ex(&module_registry, &pos);
    1644             124 :                 while (zend_hash_get_current_data_ex(&module_registry, (void *) &module, &pos) != FAILURE) {
    1645             120 :                         module_names[module->module_number] = module->name;
    1646             120 :                         i++;
    1647             120 :                         zend_hash_move_forward_ex(&module_registry, &pos);
    1648                 :                 }
    1649               2 :                 module_names[i] = "user";
    1650                 : 
    1651               2 :                 zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos);
    1652            3867 :                 while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &val, &pos) != FAILURE) {
    1653                 :                         zval *const_val;
    1654                 : 
    1655            3863 :                         if (val->module_number == PHP_USER_CONSTANT) {
    1656               1 :                                 module_number = i;
    1657            3862 :                         } else if (val->module_number > i || val->module_number < 0) {
    1658                 :                                 /* should not happen */
    1659                 :                                 goto bad_module_id;
    1660                 :                         } else {
    1661            3862 :                                 module_number = val->module_number;
    1662                 :                         }
    1663                 : 
    1664            3863 :                         if (!modules[module_number]) {
    1665              77 :                                 MAKE_STD_ZVAL(modules[module_number]);
    1666              77 :                                 array_init(modules[module_number]);
    1667              77 :                                 add_assoc_zval(return_value, module_names[module_number], modules[module_number]);
    1668                 :                         }
    1669                 : 
    1670            3863 :                         MAKE_STD_ZVAL(const_val);
    1671            3863 :                         *const_val = val->value;
    1672            3863 :                         zval_copy_ctor(const_val);
    1673            3863 :                         INIT_PZVAL(const_val);
    1674                 : 
    1675            3863 :                         add_assoc_zval_ex(modules[module_number], val->name, val->name_len, const_val);
    1676            3863 : bad_module_id:
    1677            3863 :                         zend_hash_move_forward_ex(EG(zend_constants), &pos);
    1678                 :                 }
    1679               2 :                 efree(module_names);
    1680               2 :                 efree(modules);
    1681                 :         } else {
    1682               8 :                 zend_hash_apply_with_argument(EG(zend_constants), (apply_func_arg_t) add_constant_info, return_value TSRMLS_CC);
    1683                 :         }
    1684                 : }
    1685                 : /* }}} */
    1686                 : 
    1687                 : 
    1688                 : static zval *debug_backtrace_get_args(void ***curpos TSRMLS_DC)
    1689            2003 : {
    1690            2003 :         void **p = *curpos - 2;
    1691                 :         zval *arg_array, **arg;
    1692            2003 :         int arg_count = (int)(zend_uintptr_t) *p;
    1693                 : 
    1694            2003 :         *curpos -= (arg_count+2);
    1695                 : 
    1696            2003 :         MAKE_STD_ZVAL(arg_array);
    1697            2003 :         array_init(arg_array);
    1698            2003 :         p -= arg_count;
    1699                 : 
    1700            8164 :         while (--arg_count >= 0) {
    1701            4158 :                 arg = (zval **) p++;
    1702            4158 :                 if (*arg) {
    1703            4155 :                         if (Z_TYPE_PP(arg) != IS_OBJECT) {
    1704            3832 :                                 SEPARATE_ZVAL_TO_MAKE_IS_REF(arg);
    1705                 :                         }
    1706            4155 :                         (*arg)->refcount++;
    1707            4155 :                         add_next_index_zval(arg_array, *arg);
    1708                 :                 } else {
    1709               3 :                         add_next_index_null(arg_array);
    1710                 :                 }
    1711                 :         }
    1712                 : 
    1713                 :         /* skip args from incomplete frames */
    1714            4068 :         while ((((*curpos)-1) > EG(argument_stack).elements) && *((*curpos)-1)) {
    1715              62 :                 (*curpos)--;
    1716                 :         }
    1717                 : 
    1718            2003 :         return arg_array;
    1719                 : }
    1720                 : 
    1721                 : void debug_print_backtrace_args(zval *arg_array TSRMLS_DC)
    1722              14 : {
    1723                 :         zval **tmp;
    1724                 :         HashPosition iterator;
    1725              14 :         int i = 0;
    1726                 : 
    1727              14 :         zend_hash_internal_pointer_reset_ex(arg_array->value.ht, &iterator);
    1728              45 :         while (zend_hash_get_current_data_ex(arg_array->value.ht, (void **) &tmp, &iterator) == SUCCESS) {
    1729              17 :                 if (i++) {
    1730              12 :                         ZEND_PUTS(", ");
    1731                 :                 }
    1732              17 :                 zend_print_flat_zval_r(*tmp TSRMLS_CC);
    1733              17 :                 zend_hash_move_forward_ex(arg_array->value.ht, &iterator);
    1734                 :         }
    1735              14 : }
    1736                 : 
    1737                 : /* {{{ proto void debug_print_backtrace(void) */
    1738                 : ZEND_FUNCTION(debug_print_backtrace)
    1739               7 : {
    1740                 :         zend_execute_data *ptr, *skip;
    1741                 :         int lineno;
    1742                 :         char *function_name;
    1743                 :         char *filename;
    1744               7 :         char *class_name = NULL;
    1745                 :         char *call_type;
    1746               7 :         char *include_filename = NULL;
    1747               7 :         zval *arg_array = NULL;
    1748               7 :         void **cur_arg_pos = EG(argument_stack).top_element;
    1749               7 :         void **args = cur_arg_pos;
    1750               7 :         int arg_stack_consistent = 0;
    1751               7 :         int frames_on_stack = 0;
    1752               7 :         int indent = 0;
    1753                 : 
    1754               7 :         if (ZEND_NUM_ARGS()) {
    1755               0 :                 ZEND_WRONG_PARAM_COUNT();
    1756                 :         }
    1757                 : 
    1758              28 :         while (--args > EG(argument_stack).elements) {
    1759              21 :                 if (*args--) {
    1760               0 :                         break;
    1761                 :                 }
    1762              21 :                 args -= *(ulong*)args;
    1763              21 :                 frames_on_stack++;
    1764                 : 
    1765                 :                 /* skip args from incomplete frames */
    1766              42 :                 while (((args-1) > EG(argument_stack).elements) && *(args-1)) {
    1767               0 :                         args--;
    1768                 :                 }
    1769                 : 
    1770              21 :                 if ((args-1) == EG(argument_stack).elements) {
    1771               7 :                         arg_stack_consistent = 1;
    1772               7 :                         break;
    1773                 :                 }
    1774                 :         }
    1775                 : 
    1776               7 :         ptr = EG(current_execute_data);
    1777                 : 
    1778                 :         /* skip debug_backtrace() */
    1779               7 :         ptr = ptr->prev_execute_data;
    1780               7 :         cur_arg_pos -= 2;
    1781               7 :         frames_on_stack--;
    1782                 : 
    1783               7 :         if (arg_stack_consistent) {
    1784                 :                 /* skip args from incomplete frames */
    1785              14 :                 while (((cur_arg_pos-1) > EG(argument_stack).elements) && *(cur_arg_pos-1)) {
    1786               0 :                         cur_arg_pos--;
    1787                 :                 }
    1788                 :         }
    1789                 : 
    1790              31 :         while (ptr) {
    1791              17 :                 char *free_class_name = NULL;
    1792                 : 
    1793              17 :                 class_name = call_type = NULL;   
    1794              17 :                 arg_array = NULL;
    1795                 : 
    1796              17 :                 skip = ptr;
    1797                 :                 /* skip internal handler */
    1798              17 :                 if (!skip->op_array &&
    1799                 :                     skip->prev_execute_data &&
    1800                 :                     skip->prev_execute_data->opline &&
    1801                 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
    1802                 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
    1803                 :                     skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    1804               1 :                   skip = skip->prev_execute_data;
    1805                 :                 }
    1806                 : 
    1807              17 :                 if (skip->op_array) {
    1808              15 :                         filename = skip->op_array->filename;
    1809              15 :                         lineno = skip->opline->lineno;
    1810                 :                 } else {
    1811               2 :                         filename = NULL;
    1812               2 :                         lineno = 0;
    1813                 :                 }
    1814                 : 
    1815              17 :                 function_name = ptr->function_state.function->common.function_name;
    1816                 : 
    1817              17 :                 if (function_name) {
    1818              14 :                         if (ptr->object) {
    1819               4 :                                 if (ptr->function_state.function->common.scope) {
    1820               4 :                                         class_name = ptr->function_state.function->common.scope->name;
    1821                 :                                 } else {
    1822                 :                                         zend_uint class_name_len;
    1823                 :                                         int dup;
    1824                 : 
    1825               0 :                                         dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
    1826               0 :                                         if(!dup) {
    1827               0 :                                                 free_class_name = class_name;
    1828                 :                                         }
    1829                 :                                 }
    1830                 : 
    1831               4 :                                 call_type = "->";
    1832              10 :                         } else if (ptr->function_state.function->common.scope) {
    1833               4 :                                 class_name = ptr->function_state.function->common.scope->name;
    1834               4 :                                 call_type = "::";
    1835                 :                         } else {
    1836               6 :                                 class_name = NULL;
    1837               6 :                                 call_type = NULL;
    1838                 :                         }
    1839              14 :                         if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
    1840              14 :                                 if (arg_stack_consistent && (frames_on_stack > 0)) {
    1841              14 :                                         arg_array = debug_backtrace_get_args(&cur_arg_pos TSRMLS_CC);
    1842              14 :                                         frames_on_stack--;
    1843                 :                                 }
    1844                 :                         }
    1845                 :                 } else {
    1846                 :                         /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
    1847               3 :                         zend_bool build_filename_arg = 1;
    1848                 : 
    1849               3 :                         if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    1850                 :                                 /* can happen when calling eval from a custom sapi */
    1851               0 :                                 function_name = "unknown";
    1852               0 :                                 build_filename_arg = 0;
    1853                 :                         } else
    1854               3 :                         switch (Z_LVAL(ptr->opline->op2.u.constant)) {
    1855                 :                                 case ZEND_EVAL:
    1856               1 :                                         function_name = "eval";
    1857               1 :                                         build_filename_arg = 0;
    1858               1 :                                         break;
    1859                 :                                 case ZEND_INCLUDE:
    1860               2 :                                         function_name = "include";
    1861               2 :                                         break;
    1862                 :                                 case ZEND_REQUIRE:
    1863               0 :                                         function_name = "require";
    1864               0 :                                         break;
    1865                 :                                 case ZEND_INCLUDE_ONCE:
    1866               0 :                                         function_name = "include_once";
    1867               0 :                                         break;
    1868                 :                                 case ZEND_REQUIRE_ONCE:
    1869               0 :                                         function_name = "require_once";
    1870               0 :                                         break;
    1871                 :                                 default:
    1872                 :                                         /* this can actually happen if you use debug_backtrace() in your error_handler and 
    1873                 :                                          * you're in the top-scope */
    1874               0 :                                         function_name = "unknown"; 
    1875               0 :                                         build_filename_arg = 0;
    1876                 :                                         break;
    1877                 :                         }
    1878                 : 
    1879               3 :                         if (build_filename_arg && include_filename) {
    1880               0 :                                 MAKE_STD_ZVAL(arg_array);
    1881               0 :                                 array_init(arg_array);
    1882               0 :                                 add_next_index_string(arg_array, include_filename, 1);
    1883                 :                         }
    1884               3 :                         call_type = NULL;
    1885                 :                 }
    1886              17 :                 zend_printf("#%-2d ", indent);
    1887              17 :                 if (class_name) {
    1888               8 :                         ZEND_PUTS(class_name);
    1889               8 :                         ZEND_PUTS(call_type);
    1890                 :                 }
    1891              17 :                 zend_printf("%s(", function_name?function_name:"main");
    1892              17 :                 if (arg_array) {
    1893              14 :                         debug_print_backtrace_args(arg_array TSRMLS_CC);
    1894              14 :                         zval_ptr_dtor(&arg_array);
    1895                 :                 }
    1896              17 :                 if (filename) {
    1897              15 :                         zend_printf(") called at [%s:%d]\n", filename, lineno);
    1898                 :                 } else {
    1899               2 :                         zend_execute_data *prev = skip->prev_execute_data;
    1900                 : 
    1901               4 :                         while (prev) {
    1902               2 :                                 if (prev->function_state.function &&
    1903                 :                                         prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
    1904               0 :                                         prev = NULL;
    1905               0 :                                         break;
    1906                 :                                 }                                   
    1907               2 :                                 if (prev->op_array) {
    1908               2 :                                         zend_printf(") called at [%s:%d]\n", prev->op_array->filename, prev->opline->lineno);
    1909               2 :                                         break;
    1910                 :                                 }
    1911               0 :                                 prev = prev->prev_execute_data;
    1912                 :                         }
    1913               2 :                         if (!prev) {
    1914               0 :                                 ZEND_PUTS(")\n");
    1915                 :                         }
    1916                 :                 }
    1917              17 :                 include_filename = filename;
    1918              17 :                 ptr = skip->prev_execute_data;
    1919              17 :                 ++indent;
    1920              17 :                 if (free_class_name) {
    1921               0 :                         efree(free_class_name);
    1922                 :                 }
    1923                 :         }
    1924                 : }
    1925                 : 
    1926                 : /* }}} */
    1927                 : 
    1928                 : ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int provide_object TSRMLS_DC)
    1929            1030 : {
    1930                 :         zend_execute_data *ptr, *skip;
    1931                 :         int lineno;
    1932                 :         char *function_name;
    1933                 :         char *filename;
    1934                 :         char *class_name;
    1935            1030 :         char *include_filename = NULL;
    1936                 :         zval *stack_frame;
    1937            1030 :         void **cur_arg_pos = EG(argument_stack).top_element;
    1938            1030 :         void **args = cur_arg_pos;
    1939            1030 :         int arg_stack_consistent = 0;
    1940            1030 :         int frames_on_stack = 0;
    1941                 : 
    1942            3050 :         while (--args > EG(argument_stack).elements) {
    1943            1999 :                 if (*args--) {
    1944               0 :                         break;
    1945                 :                 }
    1946            1999 :                 args -= *(ulong*)args;
    1947            1999 :                 frames_on_stack++;
    1948                 : 
    1949                 :                 /* skip args from incomplete frames */
    1950            4061 :                 while (((args-1) > EG(argument_stack).elements) && *(args-1)) {
    1951              63 :                         args--;
    1952                 :                 }
    1953                 : 
    1954            1999 :                 if ((args-1) == EG(argument_stack).elements) {
    1955            1009 :                         arg_stack_consistent = 1;
    1956            1009 :                         break;
    1957                 :                 }
    1958                 :         }
    1959                 : 
    1960            1030 :         ptr = EG(current_execute_data);
    1961                 : 
    1962                 :         /* skip "new Exception()" */
    1963            1030 :         if (ptr && (skip_last == 0) && ptr->opline && (ptr->opline->opcode == ZEND_NEW)) {
    1964             232 :                 ptr = ptr->prev_execute_data;
    1965                 :         }
    1966                 : 
    1967                 :         /* skip debug_backtrace() */
    1968            1030 :         if (skip_last-- && ptr) {
    1969               9 :                 int arg_count = *((ulong*)(cur_arg_pos - 2));
    1970               9 :                 cur_arg_pos -= (arg_count + 2);
    1971               9 :                 frames_on_stack--;
    1972               9 :                 ptr = ptr->prev_execute_data;
    1973                 : 
    1974               9 :                 if (arg_stack_consistent) {
    1975                 :                         /* skip args from incomplete frames */
    1976              19 :                         while (((cur_arg_pos-1) > EG(argument_stack).elements) && *(cur_arg_pos-1)) {
    1977               1 :                                 cur_arg_pos--;
    1978                 :                         }
    1979                 :                 }
    1980                 :         }
    1981                 : 
    1982            1030 :         array_init(return_value);
    1983                 : 
    1984            4148 :         while (ptr) {
    1985            2088 :                 MAKE_STD_ZVAL(stack_frame);
    1986            2088 :                 array_init(stack_frame);
    1987                 : 
    1988            2088 :                 skip = ptr;
    1989                 :                 /* skip internal handler */
    1990            2088 :                 if (!skip->op_array &&
    1991                 :                     skip->prev_execute_data &&
    1992                 :                     skip->prev_execute_data->opline &&
    1993                 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
    1994                 :                     skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
    1995                 :                     skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    1996              37 :                         skip = skip->prev_execute_data;
    1997                 :                 }
    1998                 : 
    1999            2088 :                 if (skip->op_array) {
    2000            1345 :                         filename = skip->op_array->filename;
    2001            1345 :                         lineno = skip->opline->lineno;
    2002            1345 :                         add_assoc_string_ex(stack_frame, "file", sizeof("file"), filename, 1);
    2003            1345 :                         add_assoc_long_ex(stack_frame, "line", sizeof("line"), lineno);
    2004                 : 
    2005                 :                         /* try to fetch args only if an FCALL was just made - elsewise we're in the middle of a function
    2006                 :                          * and debug_baktrace() might have been called by the error_handler. in this case we don't 
    2007                 :                          * want to pop anything of the argument-stack */
    2008                 :                 } else {
    2009             743 :                         zend_execute_data *prev = skip->prev_execute_data;
    2010                 : 
    2011            1486 :                         while (prev) {
    2012             737 :                                 if (prev->function_state.function &&
    2013                 :                                         prev->function_state.function->common.type != ZEND_USER_FUNCTION) {
    2014             731 :                                         break;
    2015                 :                                 }                                   
    2016               6 :                                 if (prev->op_array) {
    2017               6 :                                         add_assoc_string_ex(stack_frame, "file", sizeof("file"), prev->op_array->filename, 1);
    2018               6 :                                         add_assoc_long_ex(stack_frame, "line", sizeof("line"), prev->opline->lineno);
    2019               6 :                                         break;
    2020                 :                                 }
    2021               0 :                                 prev = prev->prev_execute_data;
    2022                 :                         }
    2023             743 :                         filename = NULL;
    2024                 :                 }
    2025                 : 
    2026            2088 :                 function_name = ptr->function_state.function->common.function_name;
    2027                 : 
    2028            2088 :                 if (function_name) {
    2029            2001 :                         add_assoc_string_ex(stack_frame, "function", sizeof("function"), function_name, 1);
    2030                 : 
    2031            3606 :                         if (ptr->object && Z_TYPE_P(ptr->object) == IS_OBJECT) {
    2032            1605 :                                 if (ptr->function_state.function->common.scope) {
    2033            1605 :                                         add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
    2034                 :                                 } else {
    2035                 :                                         zend_uint class_name_len;
    2036                 :                                         int dup;
    2037                 : 
    2038               0 :                                         dup = zend_get_object_classname(ptr->object, &class_name, &class_name_len TSRMLS_CC);
    2039               0 :                                         add_assoc_string_ex(stack_frame, "class", sizeof("class"), class_name, dup);
    2040                 :                                         
    2041                 :                                 }
    2042            1605 :                                 if (provide_object) {
    2043               5 :                                         add_assoc_zval_ex(stack_frame, "object", sizeof("object"), ptr->object);
    2044               5 :                                         ptr->object->refcount++;
    2045                 :                                 }
    2046                 : 
    2047            1605 :                                 add_assoc_string_ex(stack_frame, "type", sizeof("type"), "->", 1);
    2048             396 :                         } else if (ptr->function_state.function->common.scope) {
    2049              78 :                                 add_assoc_string_ex(stack_frame, "class", sizeof("class"), ptr->function_state.function->common.scope->name, 1);
    2050              78 :                                 add_assoc_string_ex(stack_frame, "type", sizeof("type"), "::", 1);
    2051                 :                         }
    2052                 : 
    2053            2001 :                         if ((! ptr->opline) || ((ptr->opline->opcode == ZEND_DO_FCALL_BY_NAME) || (ptr->opline->opcode == ZEND_DO_FCALL))) {
    2054            1995 :                                 if (arg_stack_consistent && (frames_on_stack > 0)) {
    2055            1989 :                                         add_assoc_zval_ex(stack_frame, "args", sizeof("args"), debug_backtrace_get_args(&cur_arg_pos TSRMLS_CC));
    2056            1989 :                                         frames_on_stack--;
    2057                 :                                 }
    2058                 :                         }
    2059                 :                 } else {
    2060                 :                         /* i know this is kinda ugly, but i'm trying to avoid extra cycles in the main execution loop */
    2061              87 :                         zend_bool build_filename_arg = 1;
    2062                 : 
    2063              91 :                         if (!ptr->opline || ptr->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
    2064                 :                                 /* can happen when calling eval from a custom sapi */
    2065               4 :                                 function_name = "unknown";
    2066               4 :                                 build_filename_arg = 0;
    2067                 :                         } else
    2068              83 :                         switch (ptr->opline->op2.u.constant.value.lval) {
    2069                 :                                 case ZEND_EVAL:
    2070               2 :                                         function_name = "eval";
    2071               2 :                                         build_filename_arg = 0;
    2072               2 :                                         break;
    2073                 :                                 case ZEND_INCLUDE:
    2074              81 :                                         function_name = "include";
    2075              81 :                                         break;
    2076                 :                                 case ZEND_REQUIRE:
    2077               0 :                                         function_name = "require";
    2078               0 :                                         break;
    2079                 :                                 case ZEND_INCLUDE_ONCE:
    2080               0 :                                         function_name = "include_once";
    2081               0 :                                         break;
    2082                 :                                 case ZEND_REQUIRE_ONCE:
    2083               0 :                                         function_name = "require_once";
    2084               0 :                                         break;
    2085                 :                                 default:
    2086                 :                                         /* this can actually happen if you use debug_backtrace() in your error_handler and 
    2087                 :                                          * you're in the top-scope */
    2088               0 :                                         function_name = "unknown"; 
    2089               0 :                                         build_filename_arg = 0;
    2090                 :                                         break;
    2091                 :                         }
    2092                 : 
    2093              87 :                         if (build_filename_arg && include_filename) {
    2094                 :                                 zval *arg_array;
    2095                 : 
    2096              80 :                                 MAKE_STD_ZVAL(arg_array);
    2097              80 :                                 array_init(arg_array);
    2098                 : 
    2099                 :                                 /* include_filename always points to the last filename of the last last called-fuction.
    2100                 :                                    if we have called include in the frame above - this is the file we have included.
    2101                 :                                  */
    2102                 : 
    2103              80 :                                 add_next_index_string(arg_array, include_filename, 1);
    2104              80 :                                 add_assoc_zval_ex(stack_frame, "args", sizeof("args"), arg_array);
    2105                 :                         }
    2106                 : 
    2107              87 :                         add_assoc_string_ex(stack_frame, "function", sizeof("function"), function_name, 1);
    2108                 :                 }
    2109                 : 
    2110            2088 :                 add_next_index_zval(return_value, stack_frame);
    2111                 : 
    2112            2088 :                 include_filename = filename; 
    2113                 : 
    2114            2088 :                 ptr = skip->prev_execute_data;
    2115                 :         }
    2116            1030 : }
    2117                 : /* }}} */
    2118                 : 
    2119                 : 
    2120                 : /* {{{ proto array debug_backtrace([bool provide_object])
    2121                 :    Return backtrace as array */
    2122                 : ZEND_FUNCTION(debug_backtrace)
    2123               8 : {
    2124               8 :         zend_bool provide_object = 1;
    2125                 :         
    2126               8 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &provide_object) == FAILURE) {
    2127               0 :                 return;
    2128                 :         }
    2129                 : 
    2130               8 :         zend_fetch_debug_backtrace(return_value, 1, provide_object TSRMLS_CC);
    2131                 : }
    2132                 : /* }}} */
    2133                 : 
    2134                 : /* {{{ proto bool extension_loaded(string extension_name)
    2135                 :    Returns true if the named extension is loaded */
    2136                 : ZEND_FUNCTION(extension_loaded)
    2137            3901 : {
    2138                 :         zval **extension_name;
    2139                 :         char *lcname;
    2140                 : 
    2141            3901 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &extension_name)) {
    2142               0 :                 ZEND_WRONG_PARAM_COUNT();
    2143                 :         }
    2144                 : 
    2145            3901 :         convert_to_string_ex(extension_name);
    2146            3901 :         lcname = zend_str_tolower_dup(Z_STRVAL_PP(extension_name), Z_STRLEN_PP(extension_name));
    2147            3901 :         if (zend_hash_exists(&module_registry, lcname, Z_STRLEN_PP(extension_name)+1)) {
    2148            3897 :                 RETVAL_TRUE;
    2149                 :         } else {
    2150               4 :                 RETVAL_FALSE;
    2151                 :         }
    2152            3901 :         efree(lcname);
    2153                 : }
    2154                 : /* }}} */
    2155                 : 
    2156                 : 
    2157                 : /* {{{ proto array get_extension_funcs(string extension_name)
    2158                 :    Returns an array with the names of functions belonging to the named extension */
    2159                 : ZEND_FUNCTION(get_extension_funcs)
    2160              32 : {
    2161                 :         zval **extension_name;
    2162                 :         zend_module_entry *module;
    2163                 :         zend_function_entry *func;
    2164                 : 
    2165              32 :         if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &extension_name)) {
    2166               3 :                 ZEND_WRONG_PARAM_COUNT();
    2167                 :         }
    2168                 : 
    2169              29 :         convert_to_string_ex(extension_name);
    2170              29 :         if (strncasecmp(Z_STRVAL_PP(extension_name), "zend", sizeof("zend"))) {
    2171              27 :                 char *lcname = zend_str_tolower_dup(Z_STRVAL_PP(extension_name), Z_STRLEN_PP(extension_name));
    2172              27 :                 if (zend_hash_find(&module_registry, lcname,
    2173                 :                         Z_STRLEN_PP(extension_name)+1, (void**)&module) == FAILURE) {
    2174              24 :                         efree(lcname);
    2175              24 :                         RETURN_FALSE;
    2176                 :                 }
    2177               3 :                 efree(lcname);
    2178                 : 
    2179               3 :                 if (!(func = module->functions)) {
    2180               0 :                         RETURN_FALSE;
    2181                 :                 }
    2182                 :         } else {
    2183               2 :                 func = builtin_functions;
    2184                 :         }
    2185                 : 
    2186               5 :         array_init(return_value);
    2187                 : 
    2188            1642 :         while (func->fname) {
    2189            1632 :                 add_next_index_string(return_value, func->fname, 1);
    2190            1632 :                 func++;
    2191                 :         }
    2192                 : }
    2193                 : /* }}} */
    2194                 : 
    2195                 : /*
    2196                 :  * Local variables:
    2197                 :  * tab-width: 4
    2198                 :  * c-basic-offset: 4
    2199                 :  * indent-tabs-mode: t
    2200                 :  * End:
    2201                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:01 +0000 (5 days ago)

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