LTP GCOV extension - code coverage report
Current view: directory - Zend - zend_API.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 1446
Code covered: 47.9 % Executed lines: 693
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2007 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                 :    |          Andrei Zmievski <andrei@php.net>                            |
      18                 :    +----------------------------------------------------------------------+
      19                 : */
      20                 : 
      21                 : /* $Id: zend_API.c,v 1.296.2.27.2.27 2007/04/09 07:30:09 tony2001 Exp $ */
      22                 : 
      23                 : #include "zend.h"
      24                 : #include "zend_execute.h"
      25                 : #include "zend_API.h"
      26                 : #include "zend_modules.h"
      27                 : #include "zend_constants.h"
      28                 : 
      29                 : #ifdef HAVE_STDARG_H
      30                 : #include <stdarg.h>
      31                 : #endif
      32                 : 
      33                 : /* these variables are true statics/globals, and have to be mutex'ed on every access */
      34                 : static int module_count=0;
      35                 : ZEND_API HashTable module_registry;
      36                 : 
      37                 : /* this function doesn't check for too many parameters */
      38                 : ZEND_API int zend_get_parameters(int ht, int param_count, ...)
      39               0 : {
      40                 :         void **p;
      41                 :         int arg_count;
      42                 :         va_list ptr;
      43                 :         zval **param, *param_ptr;
      44                 :         TSRMLS_FETCH();
      45                 : 
      46               0 :         p = EG(argument_stack).top_element-2;
      47               0 :         arg_count = (ulong) *p;
      48                 : 
      49               0 :         if (param_count>arg_count) {
      50               0 :                 return FAILURE;
      51                 :         }
      52                 : 
      53               0 :         va_start(ptr, param_count);
      54                 : 
      55               0 :         while (param_count-->0) {
      56               0 :                 param = va_arg(ptr, zval **);
      57               0 :                 param_ptr = *(p-arg_count);
      58               0 :                 if (!PZVAL_IS_REF(param_ptr) && param_ptr->refcount>1) {
      59                 :                         zval *new_tmp;
      60                 : 
      61               0 :                         ALLOC_ZVAL(new_tmp);
      62               0 :                         *new_tmp = *param_ptr;
      63               0 :                         zval_copy_ctor(new_tmp);
      64               0 :                         INIT_PZVAL(new_tmp);
      65               0 :                         param_ptr = new_tmp;
      66               0 :                         ((zval *) *(p-arg_count))->refcount--;
      67               0 :                         *(p-arg_count) = param_ptr;
      68                 :                 }
      69               0 :                 *param = param_ptr;
      70               0 :                 arg_count--;
      71                 :         }
      72               0 :         va_end(ptr);
      73                 : 
      74               0 :         return SUCCESS;
      75                 : }
      76                 : 
      77                 : 
      78                 : ZEND_API int _zend_get_parameters_array(int ht, int param_count, zval **argument_array TSRMLS_DC)
      79               0 : {
      80                 :         void **p;
      81                 :         int arg_count;
      82                 :         zval *param_ptr;
      83                 : 
      84               0 :         p = EG(argument_stack).top_element-2;
      85               0 :         arg_count = (ulong) *p;
      86                 : 
      87               0 :         if (param_count>arg_count) {
      88               0 :                 return FAILURE;
      89                 :         }
      90                 : 
      91               0 :         while (param_count-->0) {
      92               0 :                 param_ptr = *(p-arg_count);
      93               0 :                 if (!PZVAL_IS_REF(param_ptr) && param_ptr->refcount>1) {
      94                 :                         zval *new_tmp;
      95                 : 
      96               0 :                         ALLOC_ZVAL(new_tmp);
      97               0 :                         *new_tmp = *param_ptr;
      98               0 :                         zval_copy_ctor(new_tmp);
      99               0 :                         INIT_PZVAL(new_tmp);
     100               0 :                         param_ptr = new_tmp;
     101               0 :                         ((zval *) *(p-arg_count))->refcount--;
     102               0 :                         *(p-arg_count) = param_ptr;
     103                 :                 }
     104               0 :                 *(argument_array++) = param_ptr;
     105               0 :                 arg_count--;
     106                 :         }
     107                 : 
     108               0 :         return SUCCESS;
     109                 : }
     110                 : 
     111                 : 
     112                 : 
     113                 : 
     114                 : /* Zend-optimized Extended functions */
     115                 : /* this function doesn't check for too many parameters */
     116                 : ZEND_API int zend_get_parameters_ex(int param_count, ...)
     117           46740 : {
     118                 :         void **p;
     119                 :         int arg_count;
     120                 :         va_list ptr;
     121                 :         zval ***param;
     122                 :         TSRMLS_FETCH();
     123                 : 
     124           46740 :         p = EG(argument_stack).top_element-2;
     125           46740 :         arg_count = (ulong) *p;
     126                 : 
     127           46740 :         if (param_count>arg_count) {
     128               0 :                 return FAILURE;
     129                 :         }
     130                 : 
     131           46740 :         va_start(ptr, param_count);
     132          157518 :         while (param_count-->0) {
     133           64038 :                 param = va_arg(ptr, zval ***);
     134           64038 :                 *param = (zval **) p-(arg_count--);
     135                 :         }
     136           46740 :         va_end(ptr);
     137                 : 
     138           46740 :         return SUCCESS;
     139                 : }
     140                 : 
     141                 : 
     142                 : ZEND_API int _zend_get_parameters_array_ex(int param_count, zval ***argument_array TSRMLS_DC)
     143             447 : {
     144                 :         void **p;
     145                 :         int arg_count;
     146                 : 
     147             447 :         p = EG(argument_stack).top_element-2;
     148             447 :         arg_count = (ulong) *p;
     149                 : 
     150             447 :         if (param_count>arg_count) {
     151               0 :                 return FAILURE;
     152                 :         }
     153                 : 
     154            1694 :         while (param_count-->0) {
     155             800 :                 zval **value = (zval**)(p-arg_count);
     156                 : 
     157             800 :                 if (EG(ze1_compatibility_mode) && Z_TYPE_PP(value) == IS_OBJECT) {
     158                 :                         zval *value_ptr;
     159                 :                         char *class_name;
     160                 :                         zend_uint class_name_len;
     161                 :                         int dup;
     162                 :                         
     163               0 :                         dup = zend_get_object_classname(*value, &class_name, &class_name_len TSRMLS_CC);
     164                 : 
     165               0 :                         ALLOC_ZVAL(value_ptr);
     166               0 :                         *value_ptr = **value;
     167               0 :                         INIT_PZVAL(value_ptr);
     168               0 :                         zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
     169               0 :                         if(!dup) {
     170               0 :                                 efree(class_name);
     171                 :                         }
     172               0 :                         value_ptr->value.obj = Z_OBJ_HANDLER_PP(value, clone_obj)(*value TSRMLS_CC);
     173               0 :                         zval_ptr_dtor(value);
     174               0 :                         *value = value_ptr;
     175                 :                 }
     176             800 :                 *(argument_array++) = value;
     177             800 :                 arg_count--;
     178                 :         }
     179                 : 
     180             447 :         return SUCCESS;
     181                 : }
     182                 : 
     183                 : 
     184                 : ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array TSRMLS_DC)
     185               0 : {
     186                 :         void **p;
     187                 :         int arg_count;
     188                 : 
     189               0 :         p = EG(argument_stack).top_element-2;
     190               0 :         arg_count = (ulong) *p;
     191                 : 
     192               0 :         if (param_count>arg_count) {
     193               0 :                 return FAILURE;
     194                 :         }
     195                 : 
     196               0 :         while (param_count-->0) {
     197               0 :                 zval **param = (zval **) p-(arg_count--);
     198               0 :                 zval_add_ref(param);
     199               0 :                 add_next_index_zval(argument_array, *param);
     200                 :         }
     201                 : 
     202               0 :         return SUCCESS;
     203                 : }
     204                 : 
     205                 : 
     206                 : ZEND_API void zend_wrong_param_count(TSRMLS_D)
     207               0 : {
     208                 :         char *space;
     209               0 :         char *class_name = get_active_class_name(&space TSRMLS_CC);
     210                 :         
     211               0 :         zend_error(E_WARNING, "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name(TSRMLS_C));
     212               0 : }
     213                 : 
     214                 : 
     215                 : /* Argument parsing API -- andrei */
     216                 : 
     217                 : ZEND_API char *zend_get_type_by_const(int type) 
     218               0 : {
     219               0 :         switch(type) {
     220                 :                 case IS_BOOL:
     221               0 :                         return "boolean";
     222                 :                 case IS_LONG:
     223               0 :                         return "integer";
     224                 :                 case IS_DOUBLE:
     225               0 :                         return "double";
     226                 :                 case IS_STRING:
     227               0 :                         return "string";
     228                 :                 case IS_OBJECT:
     229               0 :                         return "object";
     230                 :                 case IS_RESOURCE:
     231               0 :                         return "resource";
     232                 :                 case IS_NULL:
     233               0 :                         return "null";
     234                 :                 case IS_ARRAY:
     235               0 :                         return "array";
     236                 :                 default:
     237               0 :                         return "unknown";
     238                 :         }
     239                 : }
     240                 : 
     241                 : ZEND_API char *zend_zval_type_name(zval *arg)
     242               0 : {
     243               0 :         return zend_get_type_by_const(Z_TYPE_P(arg));
     244                 : }
     245                 : 
     246                 : ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC)
     247             827 : {
     248             827 :         if (Z_OBJ_HT_P(zobject)->get_class_entry) {
     249             827 :                 return Z_OBJ_HT_P(zobject)->get_class_entry(zobject TSRMLS_CC);
     250                 :         } else {
     251               0 :                 zend_error(E_ERROR, "Class entry requested for an object without PHP class");
     252               0 :                 return NULL;
     253                 :         }
     254                 : }
     255                 : 
     256                 : /* returns 1 if you need to copy result, 0 if it's already a copy */
     257                 : ZEND_API int zend_get_object_classname(zval *object, char **class_name, zend_uint *class_name_len TSRMLS_DC)
     258              22 : {
     259              22 :         if (Z_OBJ_HT_P(object)->get_class_name == NULL ||
     260                 :                 Z_OBJ_HT_P(object)->get_class_name(object, class_name, class_name_len, 0 TSRMLS_CC) != SUCCESS) {
     261               0 :                 zend_class_entry *ce = Z_OBJCE_P(object);
     262                 : 
     263               0 :                 *class_name = ce->name;
     264               0 :                 *class_name_len = ce->name_length;
     265               0 :                 return 1;
     266                 :         }
     267              22 :         return 0;
     268                 : }
     269                 : 
     270                 : static int parse_arg_object_to_string(zval **arg, char **p, int *pl, int type TSRMLS_DC)
     271               0 : {
     272               0 :         if (Z_OBJ_HANDLER_PP(arg, cast_object)) {
     273               0 :                 SEPARATE_ZVAL_IF_NOT_REF(arg);
     274               0 :                 if (Z_OBJ_HANDLER_PP(arg, cast_object)(*arg, *arg, type TSRMLS_CC) == SUCCESS) {
     275               0 :                         *pl = Z_STRLEN_PP(arg);
     276               0 :                         *p = Z_STRVAL_PP(arg);
     277               0 :                         return SUCCESS;
     278                 :                 }
     279                 :         }
     280                 :         /* Standard PHP objects */
     281               0 :         if (Z_OBJ_HT_PP(arg) == &std_object_handlers || !Z_OBJ_HANDLER_PP(arg, cast_object)) {
     282               0 :                 SEPARATE_ZVAL_IF_NOT_REF(arg);
     283               0 :                 if (zend_std_cast_object_tostring(*arg, *arg, type TSRMLS_CC) == SUCCESS) {
     284               0 :                         *pl = Z_STRLEN_PP(arg);
     285               0 :                         *p = Z_STRVAL_PP(arg);
     286               0 :                         return SUCCESS;
     287                 :                 }
     288                 :         }
     289               0 :         if (!Z_OBJ_HANDLER_PP(arg, cast_object) && Z_OBJ_HANDLER_PP(arg, get)) {
     290                 :                 int use_copy;
     291               0 :                 zval *z = Z_OBJ_HANDLER_PP(arg, get)(*arg TSRMLS_CC);
     292               0 :                 z->refcount++;
     293               0 :                 if(Z_TYPE_P(z) != IS_OBJECT) {
     294               0 :                         zval_dtor(*arg);
     295               0 :                         Z_TYPE_P(*arg) = IS_NULL;
     296               0 :                         zend_make_printable_zval(z, *arg, &use_copy);
     297               0 :                         if (!use_copy) {
     298               0 :                                 ZVAL_ZVAL(*arg, z, 1, 1);
     299                 :                         }
     300               0 :                         *pl = Z_STRLEN_PP(arg);
     301               0 :                         *p = Z_STRVAL_PP(arg);
     302               0 :                         return SUCCESS;
     303                 :                 }
     304               0 :                 zval_ptr_dtor(&z);
     305                 :         }
     306               0 :         return FAILURE;
     307                 : }
     308                 : 
     309                 : static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **spec TSRMLS_DC)
     310           71331 : {
     311           71331 :         char *spec_walk = *spec;
     312           71331 :         char c = *spec_walk++;
     313           71331 :         int return_null = 0;
     314                 : 
     315          151114 :         while (*spec_walk == '/' || *spec_walk == '!') {
     316            8452 :                 if (*spec_walk == '/') {
     317             461 :                         SEPARATE_ZVAL_IF_NOT_REF(arg);
     318            7991 :                 } else if (*spec_walk == '!' && Z_TYPE_PP(arg) == IS_NULL) {
     319            3815 :                         return_null = 1;
     320                 :                 }
     321            8452 :                 spec_walk++;
     322                 :         }
     323                 : 
     324           71331 :         switch (c) {
     325                 :                 case 'l':
     326                 :                         {
     327           10219 :                                 long *p = va_arg(*va, long *);
     328           10219 :                                 switch (Z_TYPE_PP(arg)) {
     329                 :                                         case IS_STRING:
     330                 :                                                 {
     331                 :                                                         double d;
     332                 :                                                         int type;
     333                 : 
     334               0 :                                                         if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), p, &d, -1)) == 0) {
     335               0 :                                                                 return "long";
     336               0 :                                                         } else if (type == IS_DOUBLE) {
     337               0 :                                                                 *p = (long) d;
     338                 :                                                         }
     339                 :                                                 }
     340               0 :                                                 break;
     341                 : 
     342                 :                                         case IS_NULL:
     343                 :                                         case IS_LONG:
     344                 :                                         case IS_DOUBLE:
     345                 :                                         case IS_BOOL:
     346           10219 :                                                 convert_to_long_ex(arg);
     347           10219 :                                                 *p = Z_LVAL_PP(arg);
     348           10219 :                                                 break;
     349                 : 
     350                 :                                         case IS_ARRAY:
     351                 :                                         case IS_OBJECT:
     352                 :                                         case IS_RESOURCE:
     353                 :                                         default:
     354               0 :                                                 return "long";
     355                 :                                 }
     356                 :                         }
     357           10219 :                         break;
     358                 : 
     359                 :                 case 'd':
     360                 :                         {
     361               1 :                                 double *p = va_arg(*va, double *);
     362               1 :                                 switch (Z_TYPE_PP(arg)) {
     363                 :                                         case IS_STRING:
     364                 :                                                 {
     365                 :                                                         long l;
     366                 :                                                         int type;
     367                 : 
     368               0 :                                                         if ((type = is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &l, p, -1)) == 0) {
     369               0 :                                                                 return "double";
     370               0 :                                                         } else if (type == IS_LONG) {
     371               0 :                                                                 *p = (double) l;
     372                 :                                                         }
     373                 :                                                 }
     374               0 :                                                 break;
     375                 : 
     376                 :                                         case IS_NULL:
     377                 :                                         case IS_LONG:
     378                 :                                         case IS_DOUBLE:
     379                 :                                         case IS_BOOL:
     380               1 :                                                 convert_to_double_ex(arg);
     381               1 :                                                 *p = Z_DVAL_PP(arg);
     382               1 :                                                 break;
     383                 : 
     384                 :                                         case IS_ARRAY:
     385                 :                                         case IS_OBJECT:
     386                 :                                         case IS_RESOURCE:
     387                 :                                         default:
     388               0 :                                                 return "double";
     389                 :                                 }
     390                 :                         }
     391               1 :                         break;
     392                 : 
     393                 :                 case 's':
     394                 :                         {
     395           46382 :                                 char **p = va_arg(*va, char **);
     396           46382 :                                 int *pl = va_arg(*va, int *);
     397           46382 :                                 switch (Z_TYPE_PP(arg)) {
     398                 :                                         case IS_NULL:
     399             220 :                                                 if (return_null) {
     400             216 :                                                         *p = NULL;
     401             216 :                                                         *pl = 0;
     402             216 :                                                         break;
     403                 :                                                 }
     404                 :                                                 /* break omitted intentionally */
     405                 : 
     406                 :                                         case IS_STRING:
     407                 :                                         case IS_LONG:
     408                 :                                         case IS_DOUBLE:
     409                 :                                         case IS_BOOL:
     410           46166 :                                                 convert_to_string_ex(arg);
     411           46166 :                                                 *p = Z_STRVAL_PP(arg);
     412           46166 :                                                 *pl = Z_STRLEN_PP(arg);
     413           46166 :                                                 break;
     414                 : 
     415                 :                                         case IS_OBJECT:
     416               0 :                                                 if (parse_arg_object_to_string(arg, p, pl, IS_STRING TSRMLS_CC) == SUCCESS) {
     417               0 :                                                         break;
     418                 :                                                 }
     419                 : 
     420                 :                                         case IS_ARRAY:
     421                 :                                         case IS_RESOURCE:
     422                 :                                         default:
     423               0 :                                                 return "string";
     424                 :                                 }
     425                 :                         }
     426           46382 :                         break;
     427                 : 
     428                 :                 case 'b':
     429                 :                         {
     430              30 :                                 zend_bool *p = va_arg(*va, zend_bool *);
     431              30 :                                 switch (Z_TYPE_PP(arg)) {
     432                 :                                         case IS_NULL:
     433                 :                                         case IS_STRING:
     434                 :                                         case IS_LONG:
     435                 :                                         case IS_DOUBLE:
     436                 :                                         case IS_BOOL:
     437              30 :                                                 convert_to_boolean_ex(arg);
     438              30 :                                                 *p = Z_BVAL_PP(arg);
     439                 :                                                 break;
     440                 : 
     441                 :                                         case IS_ARRAY:
     442                 :                                         case IS_OBJECT:
     443                 :                                         case IS_RESOURCE:
     444                 :                                         default:
     445               0 :                                                 return "boolean";
     446                 :                                 }
     447                 :                         }
     448              30 :                         break;
     449                 : 
     450                 :                 case 'r':
     451                 :                         {
     452             445 :                                 zval **p = va_arg(*va, zval **);
     453             445 :                                 if (Z_TYPE_PP(arg) != IS_RESOURCE) {
     454               0 :                                         if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
     455               0 :                                                 *p = NULL;
     456                 :                                         } else {
     457               0 :                                                 return "resource";
     458                 :                                         }
     459                 :                                 } else {
     460             445 :                                         *p = *arg;
     461                 :                                 }
     462                 :                         }
     463             445 :                         break;
     464                 : 
     465                 :                 case 'a':
     466                 :                         {
     467            6188 :                                 zval **p = va_arg(*va, zval **);
     468            6188 :                                 if (Z_TYPE_PP(arg) != IS_ARRAY) {
     469            3599 :                                         if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
     470            3599 :                                                 *p = NULL;
     471                 :                                         } else {
     472               0 :                                                 return "array";
     473                 :                                         }
     474                 :                                 } else {
     475            2589 :                                         *p = *arg;
     476                 :                                 }
     477                 :                         }
     478            6188 :                         break;
     479                 : 
     480                 :                 case 'h':
     481                 :                         {
     482               0 :                                 HashTable **p = va_arg(*va, HashTable **);
     483               0 :                                 if (Z_TYPE_PP(arg) != IS_ARRAY) {
     484               0 :                                         if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
     485               0 :                                                 *p = NULL;
     486                 :                                         } else {
     487               0 :                                                 return "array";
     488                 :                                         }
     489                 :                                 } else {
     490               0 :                                         *p = Z_ARRVAL_PP(arg);
     491                 :                                 }
     492                 :                         }
     493               0 :                         break;
     494                 : 
     495                 :                 case 'o':
     496                 :                         {
     497               0 :                                 zval **p = va_arg(*va, zval **);
     498               0 :                                 if (Z_TYPE_PP(arg) != IS_OBJECT) {
     499               0 :                                         if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
     500               0 :                                                 *p = NULL;
     501                 :                                         } else {
     502               0 :                                                 return "object";
     503                 :                                         }
     504                 :                                 } else {
     505               0 :                                         *p = *arg;
     506                 :                                 }
     507                 :                         }
     508               0 :                         break;
     509                 : 
     510                 :                 case 'O':
     511                 :                         {
     512             121 :                                 zval **p = va_arg(*va, zval **);
     513             121 :                                 zend_class_entry *ce = va_arg(*va, zend_class_entry *);
     514                 : 
     515             242 :                                 if (Z_TYPE_PP(arg) == IS_OBJECT &&
     516                 :                                                 (!ce || instanceof_function(Z_OBJCE_PP(arg), ce TSRMLS_CC))) {
     517             121 :                                         *p = *arg;
     518                 :                                 } else {
     519               0 :                                         if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
     520               0 :                                                 *p = NULL;
     521               0 :                                         } else if (ce) {
     522               0 :                                                 return ce->name;
     523                 :                                         } else {
     524               0 :                                                 return "object";
     525                 :                                         }
     526                 :                                 }
     527                 :                         }
     528             121 :                         break;
     529                 : 
     530                 :                 case 'C':
     531                 :                         {
     532               0 :                                 zend_class_entry **lookup, **pce = va_arg(*va, zend_class_entry **);
     533               0 :                                 zend_class_entry *ce_base = *pce;
     534                 : 
     535               0 :                                 if (return_null && Z_TYPE_PP(arg) == IS_NULL) {
     536               0 :                                         *pce = NULL;
     537               0 :                                         break;
     538                 :                                 }
     539               0 :                                 convert_to_string_ex(arg);
     540               0 :                                 if (zend_lookup_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &lookup TSRMLS_CC) == FAILURE) {
     541               0 :                                         *pce = NULL;
     542                 :                                 } else {
     543               0 :                                         *pce = *lookup;
     544                 :                                 }
     545               0 :                                 if (ce_base) {
     546               0 :                                         if ((!*pce || !instanceof_function(*pce, ce_base TSRMLS_CC)) && !return_null) {
     547                 :                                                 char *space;
     548               0 :                                                 char *class_name = get_active_class_name(&space TSRMLS_CC);
     549               0 :                                                 zend_error(E_WARNING, "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given",
     550                 :                                                            class_name, space, get_active_function_name(TSRMLS_C),
     551                 :                                                            arg_num, ce_base->name, Z_STRVAL_PP(arg));
     552               0 :                                                 *pce = NULL;
     553               0 :                                                 return "";
     554                 :                                         }
     555                 :                                 }
     556               0 :                                 if (!*pce) {
     557                 :                                         char *space;
     558               0 :                                         char *class_name = get_active_class_name(&space TSRMLS_CC);
     559               0 :                                         zend_error(E_WARNING, "%s%s%s() expects parameter %d to be a valid class name, '%s' given",
     560                 :                                                    class_name, space, get_active_function_name(TSRMLS_C),
     561                 :                                                    arg_num, Z_STRVAL_PP(arg));
     562               0 :                                         return "";
     563                 :                                 }
     564               0 :                                 break;
     565                 : 
     566                 :                         }
     567                 :                         break;
     568                 : 
     569                 :                 case 'f':
     570                 :                         {
     571               0 :                                 zend_fcall_info       *fci = va_arg(*va, zend_fcall_info *);
     572               0 :                                 zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
     573                 : 
     574               0 :                                 if (zend_fcall_info_init(*arg, fci, fcc TSRMLS_CC) == SUCCESS) {
     575               0 :                                         break;
     576               0 :                                 } else if (return_null) {
     577               0 :                                         fci->size = 0;
     578               0 :                                         fcc->initialized = 0;
     579               0 :                                         break;
     580                 :                                 } else {
     581               0 :                                         return "function";
     582                 :                                 }
     583                 :                         }
     584                 : 
     585                 :                 case 'z':
     586                 :                         {
     587            6147 :                                 zval **p = va_arg(*va, zval **);
     588            6147 :                                 if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
     589               0 :                                         *p = NULL;
     590                 :                                 } else {
     591            6147 :                                         *p = *arg;
     592                 :                                 }
     593                 :                         }
     594            6147 :                         break;
     595                 :                 case 'Z':
     596                 :                         {
     597            1798 :                                 zval ***p = va_arg(*va, zval ***);
     598            1798 :                                 if (Z_TYPE_PP(arg) == IS_NULL && return_null) {
     599               0 :                                         *p = NULL;
     600                 :                                 } else {
     601            1798 :                                         *p = arg;
     602                 :                                 }
     603                 :                         }
     604            1798 :                         break;
     605                 :                 default:
     606               0 :                         return "unknown";
     607                 :         }
     608                 : 
     609           71331 :         *spec = spec_walk;
     610                 : 
     611           71331 :         return NULL;
     612                 : }
     613                 : 
     614                 : static int zend_parse_arg(int arg_num, zval **arg, va_list *va, char **spec, int quiet TSRMLS_DC)
     615           71331 : {
     616           71331 :         char *expected_type = NULL;
     617                 : 
     618           71331 :         expected_type = zend_parse_arg_impl(arg_num, arg, va, spec TSRMLS_CC);
     619           71331 :         if (expected_type) {
     620               0 :                 if (!quiet && *expected_type) {
     621                 :                         char *space;
     622               0 :                         char *class_name = get_active_class_name(&space TSRMLS_CC);
     623                 : 
     624               0 :                         zend_error(E_WARNING, "%s%s%s() expects parameter %d to be %s, %s given",
     625                 :                                         class_name, space, get_active_function_name(TSRMLS_C), arg_num, expected_type,
     626                 :                                         zend_zval_type_name(*arg));
     627                 :                 }
     628               0 :                 return FAILURE;
     629                 :         }
     630                 : 
     631           71331 :         return SUCCESS;
     632                 : }
     633                 : 
     634                 : static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int flags TSRMLS_DC)
     635           34397 : {
     636                 :         char *spec_walk;
     637                 :         int c, i;
     638           34397 :         int min_num_args = -1;
     639           34397 :         int max_num_args = 0;
     640                 :         zval **arg;
     641                 :         void **p;
     642                 :         int arg_count;
     643           34397 :         int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
     644                 : 
     645          207360 :         for (spec_walk = type_spec; *spec_walk; spec_walk++) {
     646          172963 :                 c = *spec_walk;
     647          172963 :                 switch (c) {
     648                 :                         case 'l': case 'd':
     649                 :                         case 's': case 'b':
     650                 :                         case 'r': case 'a':
     651                 :                         case 'o': case 'O':
     652                 :                         case 'z': case 'Z':
     653                 :                         case 'C': case 'h':
     654                 :                         case 'f':
     655          136768 :                                 max_num_args++;
     656          136768 :                                 break;
     657                 : 
     658                 :                         case '|':
     659           27272 :                                 min_num_args = max_num_args;
     660           27272 :                                 break;
     661                 : 
     662                 :                         case '/':
     663                 :                         case '!':
     664                 :                                 /* Pass */
     665            8923 :                                 break;
     666                 : 
     667                 :                         default:
     668               0 :                                 if (!quiet) {
     669               0 :                                         zend_function *active_function = EG(function_state_ptr)->function;
     670               0 :                                         char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
     671               0 :                                         zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters", 
     672                 :                                                         class_name,
     673                 :                                                         class_name[0] ? "::" : "",
     674                 :                                                         get_active_function_name(TSRMLS_C));
     675                 :                                 }
     676               0 :                                 return FAILURE;
     677                 :                 }
     678                 :         }
     679                 : 
     680           34397 :         if (min_num_args < 0) {
     681            7125 :                 min_num_args = max_num_args;
     682                 :         }
     683                 : 
     684           34397 :         if (num_args < min_num_args || num_args > max_num_args) {
     685               1 :                 if (!quiet) {
     686               0 :                         zend_function *active_function = EG(function_state_ptr)->function;
     687               0 :                         char *class_name = active_function->common.scope ? active_function->common.scope->name : "";
     688               0 :                         zend_error(E_WARNING, "%s%s%s() expects %s %d parameter%s, %d given",
     689                 :                                         class_name,
     690                 :                                         class_name[0] ? "::" : "",
     691                 :                                         get_active_function_name(TSRMLS_C),
     692                 :                                         min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
     693                 :                                         num_args < min_num_args ? min_num_args : max_num_args,
     694                 :                                         (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
     695                 :                                         num_args);
     696                 :                 }
     697               1 :                 return FAILURE;
     698                 :         }
     699                 : 
     700           34396 :         p = EG(argument_stack).top_element-2;
     701           34396 :         arg_count = (ulong) *p;
     702                 : 
     703           34396 :         if (num_args > arg_count) {
     704               0 :                 zend_error(E_WARNING, "%s(): could not obtain parameters for parsing",
     705                 :                         get_active_function_name(TSRMLS_C));
     706               0 :                 return FAILURE;
     707                 :         }
     708                 : 
     709           34396 :         i = 0;
     710          140123 :         while (num_args-- > 0) {
     711           71331 :                 arg = (zval **) p - (arg_count-i);
     712           71331 :                 if (*type_spec == '|') {
     713            5344 :                         type_spec++;
     714                 :                 }
     715           71331 :                 if (zend_parse_arg(i+1, arg, va, &type_spec, quiet TSRMLS_CC) == FAILURE) {
     716               0 :                         return FAILURE;
     717                 :                 }
     718           71331 :                 i++;
     719                 :         }
     720                 : 
     721           34396 :         return SUCCESS;
     722                 : }
     723                 : 
     724                 : ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...)
     725              13 : {
     726                 :         va_list va;
     727                 :         int retval;
     728                 : 
     729              13 :         va_start(va, type_spec);
     730              13 :         retval = zend_parse_va_args(num_args, type_spec, &va, flags TSRMLS_CC);
     731              13 :         va_end(va);
     732                 : 
     733              13 :         return retval;
     734                 : }
     735                 : 
     736                 : ZEND_API int zend_parse_parameters(int num_args TSRMLS_DC, char *type_spec, ...)
     737           34384 : {
     738                 :         va_list va;
     739                 :         int retval;
     740                 : 
     741           34384 :         va_start(va, type_spec);
     742           34384 :         retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
     743           34384 :         va_end(va);
     744                 : 
     745           34384 :         return retval;
     746                 : }
     747                 : 
     748                 : ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...)
     749               0 : {
     750                 :         va_list va;
     751                 :         int retval;
     752               0 :         char *p = type_spec;
     753                 :         zval **object;
     754                 :         zend_class_entry *ce;
     755                 : 
     756               0 :         if (!this_ptr) {
     757               0 :                 va_start(va, type_spec);
     758               0 :                 retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
     759               0 :                 va_end(va);
     760                 :         } else {
     761               0 :                 p++;
     762               0 :                 va_start(va, type_spec);
     763                 : 
     764               0 :                 object = va_arg(va, zval **);
     765               0 :                 ce = va_arg(va, zend_class_entry *);
     766               0 :                 *object = this_ptr;
     767               0 :                 if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {
     768               0 :                         zend_error(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
     769                 :                                 ce->name, get_active_function_name(TSRMLS_C), Z_OBJCE_P(this_ptr)->name, get_active_function_name(TSRMLS_C));
     770                 :                 }
     771                 : 
     772               0 :                 retval = zend_parse_va_args(num_args, p, &va, 0 TSRMLS_CC);
     773               0 :                 va_end(va);
     774                 :         }
     775               0 :         return retval;
     776                 : }
     777                 : 
     778                 : 
     779                 : ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC, zval *this_ptr, char *type_spec, ...)
     780               0 : {
     781                 :         va_list va;
     782                 :         int retval;
     783               0 :         char *p = type_spec;
     784                 :         zval **object;
     785                 :         zend_class_entry *ce;
     786               0 :         int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
     787                 : 
     788               0 :         if (!this_ptr) {
     789               0 :                 va_start(va, type_spec);
     790               0 :                 retval = zend_parse_va_args(num_args, type_spec, &va, 0 TSRMLS_CC);
     791               0 :                 va_end(va);
     792                 :         } else {
     793               0 :                 p++;
     794               0 :                 va_start(va, type_spec);
     795                 : 
     796               0 :                 object = va_arg(va, zval **);
     797               0 :                 ce = va_arg(va, zend_class_entry *);
     798               0 :                 *object = this_ptr;
     799               0 :                 if (ce && !instanceof_function(Z_OBJCE_P(this_ptr), ce TSRMLS_CC)) {
     800               0 :                         if (!quiet) {
     801               0 :                                 zend_error(E_CORE_ERROR, "%s::%s() must be derived from %s::%s",
     802                 :                                         ce->name, get_active_function_name(TSRMLS_C), Z_OBJCE_P(this_ptr)->name, get_active_function_name(TSRMLS_C));
     803                 :                         }
     804               0 :                         return FAILURE;
     805                 :                 }
     806                 : 
     807               0 :                 retval = zend_parse_va_args(num_args, p, &va, flags TSRMLS_CC);
     808               0 :                 va_end(va);
     809                 :         }
     810               0 :         return retval;
     811                 : }
     812                 : 
     813                 : 
     814                 : /* Argument parsing API -- andrei */
     815                 : 
     816                 : 
     817                 : ZEND_API int _array_init(zval *arg ZEND_FILE_LINE_DC)
     818           11563 : {
     819           11563 :         ALLOC_HASHTABLE_REL(arg->value.ht);
     820                 : 
     821           11563 :         _zend_hash_init(arg->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
     822           11563 :         arg->type = IS_ARRAY;
     823           11563 :         return SUCCESS;
     824                 : }
     825                 : 
     826                 : 
     827                 : static int zend_merge_property(zval **value, int num_args, va_list args, zend_hash_key *hash_key)
     828               0 : {
     829                 :         /* which name should a numeric property have ? */
     830               0 :         if (hash_key->nKeyLength) {
     831               0 :                 zval *obj = va_arg(args, zval *);
     832               0 :                 zend_object_handlers *obj_ht = va_arg(args, zend_object_handlers *);
     833                 :                 zval *member;
     834                 :                 TSRMLS_FETCH();
     835                 : 
     836               0 :                 MAKE_STD_ZVAL(member);
     837               0 :                 ZVAL_STRINGL(member, hash_key->arKey, hash_key->nKeyLength-1, 1);
     838               0 :                 obj_ht->write_property(obj, member, *value TSRMLS_CC);
     839               0 :                 zval_ptr_dtor(&member);
     840                 :         }
     841               0 :         return ZEND_HASH_APPLY_KEEP;
     842                 : }
     843                 : 
     844                 : 
     845                 : /* This function should be called after the constructor has been called
     846                 :  * because it may call __set from the uninitialized object otherwise. */
     847                 : ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC)
     848               0 : {
     849               0 :         zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj);
     850               0 :         zend_class_entry *old_scope = EG(scope);
     851                 : 
     852               0 :         EG(scope) = Z_OBJCE_P(obj);
     853               0 :         zend_hash_apply_with_arguments(properties, (apply_func_args_t)zend_merge_property, 2, obj, obj_ht);
     854               0 :         EG(scope) = old_scope;
     855                 : 
     856               0 :         if (destroy_ht) {
     857               0 :                 zend_hash_destroy(properties);
     858               0 :                 FREE_HASHTABLE(properties);
     859                 :         }
     860               0 : }
     861                 : 
     862                 : 
     863                 : ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC)
     864             333 : {
     865             333 :         if (!class_type->constants_updated || !CE_STATIC_MEMBERS(class_type)) {
     866              98 :                 zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
     867              98 :                 zend_class_entry *old_scope = *scope;
     868                 : 
     869              98 :                 *scope = class_type;
     870              98 :                 zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC);
     871              98 :                 zend_hash_apply_with_argument(&class_type->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
     872                 : 
     873              98 :                 if (!CE_STATIC_MEMBERS(class_type)) {
     874                 :                         HashPosition pos;
     875                 :                         zval **p;
     876                 : 
     877              93 :                         if (class_type->parent) {
     878              26 :                                 zend_update_class_constants(class_type->parent TSRMLS_CC);
     879                 :                         }
     880                 : #if ZTS
     881                 :                         ALLOC_HASHTABLE(CG(static_members)[(long)(class_type->static_members)]);
     882                 : #else
     883              93 :                         ALLOC_HASHTABLE(class_type->static_members);
     884                 : #endif
     885              93 :                         zend_hash_init(CE_STATIC_MEMBERS(class_type), zend_hash_num_elements(&class_type->default_static_members), NULL, ZVAL_PTR_DTOR, 0);
     886                 : 
     887              93 :                         zend_hash_internal_pointer_reset_ex(&class_type->default_static_members, &pos);
     888             267 :                         while (zend_hash_get_current_data_ex(&class_type->default_static_members, (void**)&p, &pos) == SUCCESS) {
     889                 :                                 char *str_index;
     890                 :                                 uint str_length;
     891                 :                                 ulong num_index;
     892                 :                                 zval **q;
     893                 : 
     894              81 :                                 zend_hash_get_current_key_ex(&class_type->default_static_members, &str_index, &str_length, &num_index, 0, &pos);
     895              81 :                                 if ((*p)->is_ref &&
     896                 :                                     class_type->parent &&
     897                 :                                     zend_hash_find(&class_type->parent->default_static_members, str_index, str_length, (void**)&q) == SUCCESS &&
     898                 :                                     *p == *q &&
     899                 :                                     zend_hash_find(CE_STATIC_MEMBERS(class_type->parent), str_index, str_length, (void**)&q) == SUCCESS) {
     900               0 :                                         (*q)->refcount++;
     901               0 :                                         (*q)->is_ref = 1;
     902               0 :                                         zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)q, sizeof(zval*), NULL);
     903                 :                                 } else {
     904                 :                                         zval *q;
     905                 : 
     906              81 :                                         ALLOC_ZVAL(q);
     907              81 :                                         *q = **p;
     908              81 :                                         INIT_PZVAL(q);
     909              81 :                                         zval_copy_ctor(q);
     910              81 :                                         zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)&q, sizeof(zval*), NULL);
     911                 :                                 }
     912              81 :                                 zend_hash_move_forward_ex(&class_type->default_static_members, &pos);
     913                 :                         }
     914                 :                 }
     915              98 :                 zend_hash_apply_with_argument(CE_STATIC_MEMBERS(class_type), (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
     916                 : 
     917              98 :                 *scope = old_scope;
     918              98 :                 class_type->constants_updated = 1;
     919                 :         }
     920             333 : }
     921                 : 
     922                 : 
     923                 : /* This function requires 'properties' to contain all props declared in the
     924                 :  * class and all props being public. If only a subset is given or the class
     925                 :  * has protected members then you need to merge the properties seperately by
     926                 :  * calling zend_merge_properties(). */
     927                 : ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC)
     928             197 : {
     929                 :         zval *tmp;
     930                 :         zend_object *object;
     931                 : 
     932             197 :         if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
     933               0 :                 char *what = class_type->ce_flags & ZEND_ACC_INTERFACE ? "interface" : "abstract class";
     934               0 :                 zend_error(E_ERROR, "Cannot instantiate %s %s", what, class_type->name);
     935                 :         }
     936                 : 
     937             197 :         zend_update_class_constants(class_type TSRMLS_CC);
     938                 : 
     939             197 :         Z_TYPE_P(arg) = IS_OBJECT;
     940             197 :         if (class_type->create_object == NULL) {
     941              61 :                 Z_OBJVAL_P(arg) = zend_objects_new(&object, class_type TSRMLS_CC);
     942              61 :                 if (properties) {
     943               4 :                         object->properties = properties;
     944                 :                 } else {
     945              57 :                         ALLOC_HASHTABLE_REL(object->properties);
     946              57 :                         zend_hash_init(object->properties, zend_hash_num_elements(&class_type->default_properties), NULL, ZVAL_PTR_DTOR, 0);
     947              57 :                         zend_hash_copy(object->properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     948                 :                 }
     949                 :         } else {
     950             136 :                 Z_OBJVAL_P(arg) = class_type->create_object(class_type TSRMLS_CC);
     951                 :         }
     952             197 :         return SUCCESS;
     953                 : }
     954                 : 
     955                 : ZEND_API int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC TSRMLS_DC)
     956             193 : {
     957             193 :         return _object_and_properties_init(arg, class_type, 0 ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
     958                 : }
     959                 : 
     960                 : ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC)
     961              57 : {
     962              57 :         return _object_init_ex(arg, zend_standard_class_def ZEND_FILE_LINE_RELAY_CC TSRMLS_CC);
     963                 : }
     964                 : 
     965                 : 
     966                 : ZEND_API int add_assoc_function(zval *arg, char *key, void (*function_ptr)(INTERNAL_FUNCTION_PARAMETERS))
     967               0 : {
     968               0 :         zend_error(E_WARNING, "add_assoc_function() is no longer supported");
     969               0 :         return FAILURE;
     970                 : }
     971                 : 
     972                 : 
     973                 : ZEND_API int add_assoc_long_ex(zval *arg, char *key, uint key_len, long n)
     974            1929 : {
     975                 :         zval *tmp;
     976                 : 
     977            1929 :         MAKE_STD_ZVAL(tmp);
     978            1929 :         ZVAL_LONG(tmp, n);
     979                 : 
     980            1929 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
     981                 : }
     982                 : 
     983                 : ZEND_API int add_assoc_null_ex(zval *arg, char *key, uint key_len)
     984               8 : {
     985                 :         zval *tmp;
     986                 : 
     987               8 :         MAKE_STD_ZVAL(tmp);
     988               8 :         ZVAL_NULL(tmp);
     989                 : 
     990               8 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
     991                 : }
     992                 : 
     993                 : ZEND_API int add_assoc_bool_ex(zval *arg, char *key, uint key_len, int b)
     994             648 : {
     995                 :         zval *tmp;
     996                 : 
     997             648 :         MAKE_STD_ZVAL(tmp);
     998             648 :         ZVAL_BOOL(tmp, b);
     999                 : 
    1000             648 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
    1001                 : }
    1002                 : 
    1003                 : ZEND_API int add_assoc_resource_ex(zval *arg, char *key, uint key_len, int r)
    1004               0 : {
    1005                 :         zval *tmp;
    1006                 : 
    1007               0 :         MAKE_STD_ZVAL(tmp);
    1008               0 :         ZVAL_RESOURCE(tmp, r);
    1009                 : 
    1010               0 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
    1011                 : }
    1012                 : 
    1013                 : 
    1014                 : ZEND_API int add_assoc_double_ex(zval *arg, char *key, uint key_len, double d)
    1015            1085 : {
    1016                 :         zval *tmp;
    1017                 : 
    1018            1085 :         MAKE_STD_ZVAL(tmp);
    1019            1085 :         ZVAL_DOUBLE(tmp, d);
    1020                 : 
    1021            1085 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
    1022                 : }
    1023                 : 
    1024                 : 
    1025                 : ZEND_API int add_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, int duplicate)
    1026             657 : {
    1027                 :         zval *tmp;
    1028                 : 
    1029             657 :         MAKE_STD_ZVAL(tmp);
    1030             657 :         ZVAL_STRING(tmp, str, duplicate);
    1031                 : 
    1032             657 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
    1033                 : }
    1034                 : 
    1035                 : 
    1036                 : ZEND_API int add_assoc_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, int duplicate)
    1037             790 : {
    1038                 :         zval *tmp;
    1039                 : 
    1040             790 :         MAKE_STD_ZVAL(tmp);
    1041             790 :         ZVAL_STRINGL(tmp, str, length, duplicate);
    1042                 : 
    1043             790 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), NULL);
    1044                 : }
    1045                 : 
    1046                 : ZEND_API int add_assoc_zval_ex(zval *arg, char *key, uint key_len, zval *value)
    1047             565 : {
    1048             565 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &value, sizeof(zval *), NULL);
    1049                 : }
    1050                 : 
    1051                 : 
    1052                 : ZEND_API int add_index_long(zval *arg, ulong index, long n)
    1053              44 : {
    1054                 :         zval *tmp;
    1055                 : 
    1056              44 :         MAKE_STD_ZVAL(tmp);
    1057              44 :         ZVAL_LONG(tmp, n);
    1058                 : 
    1059              44 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
    1060                 : }
    1061                 : 
    1062                 : 
    1063                 : ZEND_API int add_index_null(zval *arg, ulong index)
    1064               0 : {
    1065                 :         zval *tmp;
    1066                 : 
    1067               0 :         MAKE_STD_ZVAL(tmp);
    1068               0 :         ZVAL_NULL(tmp);
    1069                 : 
    1070               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
    1071                 : }
    1072                 : 
    1073                 : ZEND_API int add_index_bool(zval *arg, ulong index, int b)
    1074               0 : {
    1075                 :         zval *tmp;
    1076                 : 
    1077               0 :         MAKE_STD_ZVAL(tmp);
    1078               0 :         ZVAL_BOOL(tmp, b);
    1079                 : 
    1080               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
    1081                 : }
    1082                 : 
    1083                 : 
    1084                 : ZEND_API int add_index_resource(zval *arg, ulong index, int r)
    1085               0 : {
    1086                 :         zval *tmp;
    1087                 : 
    1088               0 :         MAKE_STD_ZVAL(tmp);
    1089               0 :         ZVAL_RESOURCE(tmp, r);
    1090                 : 
    1091               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
    1092                 : }
    1093                 : 
    1094                 : 
    1095                 : ZEND_API int add_index_double(zval *arg, ulong index, double d)
    1096               0 : {
    1097                 :         zval *tmp;
    1098                 : 
    1099               0 :         MAKE_STD_ZVAL(tmp);
    1100               0 :         ZVAL_DOUBLE(tmp, d);
    1101                 : 
    1102               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
    1103                 : }
    1104                 : 
    1105                 : 
    1106                 : ZEND_API int add_index_string(zval *arg, ulong index, char *str, int duplicate)
    1107               0 : {
    1108                 :         zval *tmp;
    1109                 : 
    1110               0 :         MAKE_STD_ZVAL(tmp);
    1111               0 :         ZVAL_STRING(tmp, str, duplicate);
    1112                 : 
    1113               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
    1114                 : }
    1115                 : 
    1116                 : 
    1117                 : ZEND_API int add_index_stringl(zval *arg, ulong index, char *str, uint length, int duplicate)
    1118              51 : {
    1119                 :         zval *tmp;
    1120                 : 
    1121              51 :         MAKE_STD_ZVAL(tmp);
    1122              51 :         ZVAL_STRINGL(tmp, str, length, duplicate);
    1123                 :         
    1124              51 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), NULL);
    1125                 : }
    1126                 : 
    1127                 : 
    1128                 : ZEND_API int add_index_zval(zval *arg, ulong index, zval *value)
    1129             701 : {
    1130             701 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &value, sizeof(zval *), NULL);
    1131                 : }
    1132                 : 
    1133                 : 
    1134                 : ZEND_API int add_next_index_long(zval *arg, long n)
    1135               0 : {
    1136                 :         zval *tmp;
    1137                 : 
    1138               0 :         MAKE_STD_ZVAL(tmp);
    1139               0 :         ZVAL_LONG(tmp, n);
    1140                 : 
    1141               0 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
    1142                 : }
    1143                 : 
    1144                 : 
    1145                 : ZEND_API int add_next_index_null(zval *arg)
    1146               0 : {
    1147                 :         zval *tmp;
    1148                 : 
    1149               0 :         MAKE_STD_ZVAL(tmp);
    1150               0 :         ZVAL_NULL(tmp);
    1151                 : 
    1152               0 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
    1153                 : }
    1154                 : 
    1155                 : 
    1156                 : ZEND_API int add_next_index_bool(zval *arg, int b)
    1157               0 : {
    1158                 :         zval *tmp;
    1159                 : 
    1160               0 :         MAKE_STD_ZVAL(tmp);
    1161               0 :         ZVAL_BOOL(tmp, b);
    1162                 : 
    1163               0 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
    1164                 : }
    1165                 : 
    1166                 : 
    1167                 : ZEND_API int add_next_index_resource(zval *arg, int r)
    1168               0 : {
    1169                 :         zval *tmp;
    1170                 : 
    1171               0 :         MAKE_STD_ZVAL(tmp);
    1172               0 :         ZVAL_RESOURCE(tmp, r);
    1173                 : 
    1174               0 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
    1175                 : }
    1176                 : 
    1177                 : 
    1178                 : ZEND_API int add_next_index_double(zval *arg, double d)
    1179               0 : {
    1180                 :         zval *tmp;
    1181                 : 
    1182               0 :         MAKE_STD_ZVAL(tmp);
    1183               0 :         ZVAL_DOUBLE(tmp, d);
    1184                 : 
    1185               0 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
    1186                 : }
    1187                 : 
    1188                 : 
    1189                 : ZEND_API int add_next_index_string(zval *arg, char *str, int duplicate)
    1190             215 : {
    1191                 :         zval *tmp;
    1192                 : 
    1193             215 :         MAKE_STD_ZVAL(tmp);
    1194             215 :         ZVAL_STRING(tmp, str, duplicate);
    1195                 : 
    1196             215 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
    1197                 : }
    1198                 : 
    1199                 : 
    1200                 : ZEND_API int add_next_index_stringl(zval *arg, char *str, uint length, int duplicate)
    1201            5779 : {
    1202                 :         zval *tmp;
    1203                 : 
    1204            5779 :         MAKE_STD_ZVAL(tmp);
    1205            5779 :         ZVAL_STRINGL(tmp, str, length, duplicate);
    1206                 : 
    1207            5779 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &tmp, sizeof(zval *), NULL);
    1208                 : }
    1209                 : 
    1210                 : 
    1211                 : ZEND_API int add_next_index_zval(zval *arg, zval *value)
    1212              94 : {
    1213              94 :         return zend_hash_next_index_insert(Z_ARRVAL_P(arg), &value, sizeof(zval *), NULL);
    1214                 : }
    1215                 : 
    1216                 : 
    1217                 : ZEND_API int add_get_assoc_string_ex(zval *arg, char *key, uint key_len, char *str, void **dest, int duplicate)
    1218               0 : {
    1219                 :         zval *tmp;
    1220                 : 
    1221               0 :         MAKE_STD_ZVAL(tmp);
    1222               0 :         ZVAL_STRING(tmp, str, duplicate);
    1223                 : 
    1224               0 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), dest);
    1225                 : }
    1226                 : 
    1227                 : 
    1228                 : ZEND_API int add_get_assoc_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, void **dest, int duplicate)
    1229               0 : {
    1230                 :         zval *tmp;
    1231                 : 
    1232               0 :         MAKE_STD_ZVAL(tmp);
    1233               0 :         ZVAL_STRINGL(tmp, str, length, duplicate);
    1234                 : 
    1235               0 :         return zend_symtable_update(Z_ARRVAL_P(arg), key, key_len, (void *) &tmp, sizeof(zval *), dest);
    1236                 : }
    1237                 : 
    1238                 : 
    1239                 : ZEND_API int add_get_index_long(zval *arg, ulong index, long l, void **dest)
    1240               0 : {
    1241                 :         zval *tmp;
    1242                 : 
    1243               0 :         MAKE_STD_ZVAL(tmp);
    1244               0 :         ZVAL_LONG(tmp, l);
    1245                 : 
    1246               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
    1247                 : }
    1248                 : 
    1249                 : 
    1250                 : ZEND_API int add_get_index_double(zval *arg, ulong index, double d, void **dest)
    1251               0 : {
    1252                 :         zval *tmp;
    1253                 : 
    1254               0 :         MAKE_STD_ZVAL(tmp);
    1255               0 :         ZVAL_DOUBLE(tmp, d);
    1256                 : 
    1257               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
    1258                 : }
    1259                 : 
    1260                 : 
    1261                 : ZEND_API int add_get_index_string(zval *arg, ulong index, char *str, void **dest, int duplicate)
    1262               0 : {
    1263                 :         zval *tmp;
    1264                 : 
    1265               0 :         MAKE_STD_ZVAL(tmp);
    1266               0 :         ZVAL_STRING(tmp, str, duplicate);
    1267                 :         
    1268               0 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
    1269                 : }
    1270                 : 
    1271                 : 
    1272                 : ZEND_API int add_get_index_stringl(zval *arg, ulong index, char *str, uint length, void **dest, int duplicate)
    1273              45 : {
    1274                 :         zval *tmp;
    1275                 :         
    1276              45 :         MAKE_STD_ZVAL(tmp);
    1277              45 :         ZVAL_STRINGL(tmp, str, length, duplicate);
    1278                 :         
    1279              45 :         return zend_hash_index_update(Z_ARRVAL_P(arg), index, (void *) &tmp, sizeof(zval *), dest);
    1280                 : }
    1281                 : 
    1282                 : 
    1283                 : ZEND_API int add_property_long_ex(zval *arg, char *key, uint key_len, long n TSRMLS_DC)
    1284               0 : {
    1285                 :         zval *tmp;
    1286                 :         zval *z_key;
    1287                 : 
    1288               0 :         MAKE_STD_ZVAL(tmp);
    1289               0 :         ZVAL_LONG(tmp, n);
    1290                 :         
    1291               0 :         MAKE_STD_ZVAL(z_key);
    1292               0 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1293                 : 
    1294               0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
    1295               0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1296               0 :         zval_ptr_dtor(&z_key);
    1297               0 :         return SUCCESS;
    1298                 : }
    1299                 : 
    1300                 : ZEND_API int add_property_bool_ex(zval *arg, char *key, uint key_len, int b TSRMLS_DC)
    1301               0 : {
    1302                 :         zval *tmp;
    1303                 :         zval *z_key;
    1304                 : 
    1305               0 :         MAKE_STD_ZVAL(tmp);
    1306               0 :         ZVAL_BOOL(tmp, b);
    1307                 : 
    1308               0 :         MAKE_STD_ZVAL(z_key);
    1309               0 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1310                 : 
    1311               0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
    1312               0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1313               0 :         zval_ptr_dtor(&z_key);
    1314               0 :         return SUCCESS;
    1315                 : }
    1316                 : 
    1317                 : ZEND_API int add_property_null_ex(zval *arg, char *key, uint key_len TSRMLS_DC)
    1318               0 : {
    1319                 :         zval *tmp;
    1320                 :         zval *z_key;
    1321                 :         
    1322               0 :         MAKE_STD_ZVAL(tmp);
    1323               0 :         ZVAL_NULL(tmp);
    1324                 :         
    1325               0 :         MAKE_STD_ZVAL(z_key);
    1326               0 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1327                 : 
    1328               0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
    1329               0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1330               0 :         zval_ptr_dtor(&z_key);
    1331               0 :         return SUCCESS;
    1332                 : }
    1333                 : 
    1334                 : ZEND_API int add_property_resource_ex(zval *arg, char *key, uint key_len, long n TSRMLS_DC)
    1335               0 : {
    1336                 :         zval *tmp;
    1337                 :         zval *z_key;
    1338                 :         
    1339               0 :         MAKE_STD_ZVAL(tmp);
    1340               0 :         ZVAL_RESOURCE(tmp, n);
    1341                 : 
    1342               0 :         MAKE_STD_ZVAL(z_key);
    1343               0 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1344                 : 
    1345               0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
    1346               0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1347               0 :         zval_ptr_dtor(&z_key);
    1348               0 :         return SUCCESS;
    1349                 : }
    1350                 : 
    1351                 : 
    1352                 : ZEND_API int add_property_double_ex(zval *arg, char *key, uint key_len, double d TSRMLS_DC)
    1353               0 : {
    1354                 :         zval *tmp;
    1355                 :         zval *z_key;
    1356                 : 
    1357               0 :         MAKE_STD_ZVAL(tmp);
    1358               0 :         ZVAL_DOUBLE(tmp, d);
    1359                 :         
    1360               0 :         MAKE_STD_ZVAL(z_key);
    1361               0 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1362                 : 
    1363               0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
    1364               0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1365               0 :         zval_ptr_dtor(&z_key);
    1366               0 :         return SUCCESS;
    1367                 : }
    1368                 : 
    1369                 : 
    1370                 : ZEND_API int add_property_string_ex(zval *arg, char *key, uint key_len, char *str, int duplicate TSRMLS_DC)
    1371               0 : {
    1372                 :         zval *tmp;
    1373                 :         zval *z_key;
    1374                 : 
    1375               0 :         MAKE_STD_ZVAL(tmp);
    1376               0 :         ZVAL_STRING(tmp, str, duplicate);
    1377                 : 
    1378               0 :         MAKE_STD_ZVAL(z_key);
    1379               0 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1380                 : 
    1381               0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
    1382               0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1383               0 :         zval_ptr_dtor(&z_key);
    1384               0 :         return SUCCESS;
    1385                 : }
    1386                 : 
    1387                 : ZEND_API int add_property_stringl_ex(zval *arg, char *key, uint key_len, char *str, uint length, int duplicate TSRMLS_DC)
    1388               0 : {
    1389                 :         zval *tmp;
    1390                 :         zval *z_key;
    1391                 : 
    1392               0 :         MAKE_STD_ZVAL(tmp);
    1393               0 :         ZVAL_STRINGL(tmp, str, length, duplicate);
    1394                 : 
    1395               0 :         MAKE_STD_ZVAL(z_key);
    1396               0 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1397                 : 
    1398               0 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, tmp TSRMLS_CC);
    1399               0 :         zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
    1400               0 :         zval_ptr_dtor(&z_key);
    1401               0 :         return SUCCESS;
    1402                 : }
    1403                 : 
    1404                 : ZEND_API int add_property_zval_ex(zval *arg, char *key, uint key_len, zval *value TSRMLS_DC)
    1405               6 : {
    1406                 :         zval *z_key;
    1407                 : 
    1408               6 :         MAKE_STD_ZVAL(z_key);
    1409               6 :         ZVAL_STRINGL(z_key, key, key_len-1, 1);
    1410                 : 
    1411               6 :         Z_OBJ_HANDLER_P(arg, write_property)(arg, z_key, value TSRMLS_CC);
    1412               6 :         zval_ptr_dtor(&z_key);
    1413               6 :         return SUCCESS;
    1414                 : }
    1415                 : 
    1416                 : ZEND_API int zend_startup_module_ex(zend_module_entry *module TSRMLS_DC)
    1417            2199 : {
    1418                 :         int name_len;
    1419                 :         char *lcname;
    1420                 : 
    1421            2199 :         if (module->module_started) {
    1422               0 :                 return SUCCESS;
    1423                 :         }
    1424            2199 :         module->module_started = 1;
    1425                 : 
    1426                 :         /* Check module dependencies */
    1427            2199 :         if (module->deps) {
    1428             660 :                 zend_module_dep *dep = module->deps;
    1429                 : 
    1430            2640 :                 while (dep->name) {
    1431            1320 :                         if (dep->type == MODULE_DEP_REQUIRED) {
    1432                 :                                 zend_module_entry *req_mod;
    1433                 : 
    1434             880 :                                 name_len = strlen(dep->name);
    1435             880 :                                 lcname = zend_str_tolower_dup(dep->name, name_len);
    1436                 : 
    1437             880 :                                 if (zend_hash_find(&module_registry, lcname, name_len+1, (void**)&req_mod) == FAILURE ||
    1438                 :                                     !req_mod->module_started) {
    1439               0 :                                         efree(lcname);
    1440                 :                                         /* TODO: Check version relationship */
    1441               0 :                                         zend_error(E_CORE_WARNING, "Cannot load module '%s' because required module '%s' is not loaded", module->name, dep->name);
    1442               0 :                                         module->module_started = 0;
    1443               0 :                                         return FAILURE;
    1444                 :                                 }
    1445             880 :                                 efree(lcname);
    1446                 :                         }
    1447            1320 :                         ++dep;
    1448                 :                 }
    1449                 :         }
    1450                 : 
    1451                 :         /* Initialize module globals */
    1452            2199 :         if (module->globals_size) {
    1453                 : #ifdef ZTS
    1454                 :                 ts_allocate_id(module->globals_id_ptr, module->globals_size, (ts_allocate_ctor) module->globals_ctor, (ts_allocate_dtor) module->globals_dtor);
    1455                 : #else
    1456            1100 :                 if (module->globals_ctor) {
    1457            1100 :                         module->globals_ctor(module->globals_ptr TSRMLS_CC);
    1458                 :                 }
    1459                 : #endif
    1460                 :         }
    1461                 : 
    1462            2199 :         if (module->module_startup_func) {
    1463            2199 :                 EG(current_module) = module;
    1464            2199 :                 if (module->module_startup_func(module->type, module->module_number TSRMLS_CC)==FAILURE) {
    1465               0 :                         zend_error(E_CORE_ERROR,"Unable to start %s module", module->name);
    1466               0 :                         EG(current_module) = NULL;
    1467               0 :                         return FAILURE;
    1468                 :                 }
    1469            2199 :                 EG(current_module) = NULL;
    1470                 :         }
    1471            2199 :         return SUCCESS;
    1472                 : }
    1473                 : 
    1474                 : static void zend_sort_modules(void *base, size_t count, size_t siz, compare_func_t compare TSRMLS_DC)
    1475             220 : {
    1476             220 :         Bucket **b1 = base;
    1477                 :         Bucket **b2;
    1478             220 :         Bucket **end = b1 + count;
    1479                 :         Bucket *tmp;
    1480                 :         zend_module_entry *m, *r;
    1481                 : 
    1482            2639 :         while (b1 < end) {
    1483            2859 : try_again:
    1484            2859 :                 m = (zend_module_entry*)(*b1)->pData;
    1485            2859 :                 if (!m->module_started && m->deps) {
    1486            1320 :                         zend_module_dep *dep = m->deps;
    1487            4180 :                         while (dep->name) {
    1488            2200 :                                 if (dep->type == MODULE_DEP_REQUIRED || dep->type == MODULE_DEP_OPTIONAL) {
    1489            2200 :                                         b2 = b1 + 1;
    1490           10333 :                                         while (b2 < end) {
    1491            6593 :                                         r = (zend_module_entry*)(*b2)->pData;
    1492            6593 :                                         if (strcasecmp(dep->name, r->name) == 0) {
    1493             660 :                                                 tmp  = *b1;
    1494             660 :                                                 *b1 = *b2;
    1495             660 :                                                 *b2 = tmp;
    1496             660 :                                           goto try_again;
    1497                 :                                         }
    1498            5933 :                                         b2++;
    1499                 :                                   }
    1500                 :                           }
    1501            1540 :                           dep++;
    1502                 :                         }
    1503                 :                 }
    1504            2199 :                 b1++;
    1505                 :         }
    1506             220 : }
    1507                 : 
    1508                 : ZEND_API int zend_startup_modules(TSRMLS_D)
    1509             220 : {
    1510             220 :         zend_hash_sort(&module_registry, zend_sort_modules, NULL, 0 TSRMLS_CC);
    1511             220 :         zend_hash_apply(&module_registry, (apply_func_t)zend_startup_module_ex TSRMLS_CC);
    1512             220 :         return SUCCESS;
    1513                 : }
    1514                 : 
    1515                 : ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TSRMLS_DC)
    1516            2199 : {
    1517                 :         int name_len;
    1518                 :         char *lcname;
    1519                 :         zend_module_entry *module_ptr;
    1520                 : 
    1521            2199 :         if (!module) {
    1522               0 :                 return NULL;
    1523                 :         }
    1524                 : 
    1525                 : #if 0
    1526                 :         zend_printf("%s:  Registering module %d\n", module->name, module->module_number);
    1527                 : #endif
    1528                 : 
    1529                 :         /* Check module dependencies */
    1530            2199 :         if (module->deps) {
    1531             660 :                 zend_module_dep *dep = module->deps;
    1532                 : 
    1533            2640 :                 while (dep->name) {
    1534            1320 :                         if (dep->type == MODULE_DEP_CONFLICTS) {
    1535               0 :                                 name_len = strlen(dep->name);
    1536               0 :                                 lcname = zend_str_tolower_dup(dep->name, name_len);
    1537                 : 
    1538               0 :                                 if (zend_hash_exists(&module_registry, lcname, name_len+1)) {
    1539               0 :                                         efree(lcname);
    1540                 :                                         /* TODO: Check version relationship */
    1541               0 :                                         zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
    1542               0 :                                         return NULL;
    1543                 :                                 }
    1544               0 :                                 efree(lcname);
    1545                 :                         }
    1546            1320 :                         ++dep;
    1547                 :                 }
    1548                 :         }
    1549                 : 
    1550            2199 :         name_len = strlen(module->name);
    1551            2199 :         lcname = zend_str_tolower_dup(module->name, name_len);
    1552                 : 
    1553            2199 :         if (zend_hash_add(&module_registry, lcname, name_len+1, (void *)module, sizeof(zend_module_entry), (void**)&module_ptr)==FAILURE) {
    1554               0 :                 zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
    1555               0 :                 efree(lcname);
    1556               0 :                 return NULL;
    1557                 :         }
    1558            2199 :         efree(lcname);
    1559            2199 :         module = module_ptr;
    1560            2199 :         EG(current_module) = module;
    1561                 : 
    1562            2199 :         if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type TSRMLS_CC)==FAILURE) {
    1563               0 :                 EG(current_module) = NULL;
    1564               0 :                 zend_error(E_CORE_WARNING,"%s:  Unable to register functions, unable to load", module->name);
    1565               0 :                 return NULL;
    1566                 :         }
    1567                 : 
    1568            2199 :         EG(current_module) = NULL;
    1569            2199 :         return module;
    1570                 : }
    1571                 : 
    1572                 : ZEND_API zend_module_entry* zend_register_internal_module(zend_module_entry *module TSRMLS_DC)
    1573            2199 : {
    1574            2199 :         module->module_number = zend_next_free_module();
    1575            2199 :         module->type = MODULE_PERSISTENT;
    1576            2199 :         return zend_register_module_ex(module TSRMLS_CC);
    1577                 : }
    1578                 : 
    1579                 : ZEND_API void zend_check_magic_method_implementation(zend_class_entry *ce, zend_function *fptr, int error_type TSRMLS_DC)
    1580           12990 : {
    1581                 :         char lcname[16];
    1582                 :         int name_len;
    1583                 : 
    1584                 :         /* we don't care if the function name is longer, in fact lowercasing only 
    1585                 :          * the beginning of the name speeds up the check process */
    1586           12990 :         name_len = strlen(fptr->common.function_name);
    1587           12990 :         zend_str_tolower_copy(lcname, fptr->common.function_name, MIN(name_len, sizeof(lcname)-1));
    1588           12990 :         lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
    1589                 : 
    1590           12990 :         if (name_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME)) && fptr->common.num_args != 0) {
    1591               0 :                 zend_error(error_type, "Destructor %s::%s() cannot take arguments", ce->name, ZEND_DESTRUCTOR_FUNC_NAME);
    1592           12990 :         } else if (name_len == sizeof(ZEND_CLONE_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME)) && fptr->common.num_args != 0) {
    1593               0 :                 zend_error(error_type, "Method %s::%s() cannot accept any arguments", ce->name, ZEND_CLONE_FUNC_NAME);
    1594           12990 :         } else if (name_len == sizeof(ZEND_GET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME)) && fptr->common.num_args != 1) {
    1595               0 :                 zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_GET_FUNC_NAME);
    1596           12990 :         } else if (name_len == sizeof(ZEND_SET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)) && fptr->common.num_args != 2) {
    1597               0 :                 zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_SET_FUNC_NAME);
    1598           12990 :         } else if (name_len == sizeof(ZEND_UNSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME)) && fptr->common.num_args != 1) {
    1599               0 :                 zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_UNSET_FUNC_NAME);
    1600           12990 :         } else if (name_len == sizeof(ZEND_ISSET_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME)) && fptr->common.num_args != 1) {
    1601               0 :                 zend_error(error_type, "Method %s::%s() must take exactly 1 argument", ce->name, ZEND_ISSET_FUNC_NAME);
    1602           12990 :         } else if (name_len == sizeof(ZEND_CALL_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)) && fptr->common.num_args != 2) {
    1603               0 :                 zend_error(error_type, "Method %s::%s() must take exactly 2 arguments", ce->name, ZEND_CALL_FUNC_NAME);
    1604                 :         }
    1605           12990 : }
    1606                 : 
    1607                 : /* registers all functions in *library_functions in the function hash */
    1608                 : ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC)
    1609           14960 : {
    1610           14960 :         zend_function_entry *ptr = functions;
    1611                 :         zend_function function, *reg_function;
    1612           14960 :         zend_internal_function *internal_function = (zend_internal_function *)&function;
    1613           14960 :         int count=0, unload=0;
    1614           14960 :         HashTable *target_function_table = function_table;
    1615                 :         int error_type;
    1616           14960 :         zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__tostring = NULL;
    1617                 :         char *lowercase_name;
    1618                 :         int fname_len;
    1619           14960 :         char *lc_class_name = NULL;
    1620           14960 :         int class_name_len = 0;
    1621                 : 
    1622           14960 :         if (type==MODULE_PERSISTENT) {
    1623           14960 :                 error_type = E_CORE_WARNING;
    1624                 :         } else {
    1625               0 :                 error_type = E_WARNING;
    1626                 :         }
    1627                 : 
    1628           14960 :         if (!target_function_table) {
    1629            2200 :                 target_function_table = CG(function_table);
    1630                 :         }
    1631           14960 :         internal_function->type = ZEND_INTERNAL_FUNCTION;
    1632                 :         
    1633           14960 :         if (scope) {
    1634           12760 :                 class_name_len = strlen(scope->name);
    1635           12760 :                 lc_class_name = zend_str_tolower_dup(scope->name, class_name_len);
    1636                 :         }
    1637                 : 
    1638          320760 :         while (ptr->fname) {
    1639          290840 :                 internal_function->handler = ptr->handler;
    1640          290840 :                 internal_function->function_name = ptr->fname;
    1641          290840 :                 internal_function->scope = scope;
    1642          290840 :                 internal_function->prototype = NULL;
    1643          290840 :                 if (ptr->arg_info) {
    1644          198220 :                         internal_function->arg_info = ptr->arg_info+1;
    1645          198220 :                         internal_function->num_args = ptr->num_args;
    1646                 :                         /* Currently you cannot denote that the function can accept less arguments than num_args */
    1647          198220 :                         if (ptr->arg_info[0].required_num_args == -1) {
    1648           88660 :                                 internal_function->required_num_args = ptr->num_args;
    1649                 :                         } else {
    1650          109560 :                                 internal_function->required_num_args = ptr->arg_info[0].required_num_args;
    1651                 :                         }
    1652          198220 :                         internal_function->pass_rest_by_reference = ptr->arg_info[0].pass_by_reference;
    1653          198220 :                         internal_function->return_reference = ptr->arg_info[0].return_reference;
    1654                 :                 } else {
    1655           92620 :                         internal_function->arg_info = NULL;
    1656           92620 :                         internal_function->num_args = 0;
    1657           92620 :                         internal_function->required_num_args = 0;
    1658           92620 :                         internal_function->pass_rest_by_reference = 0;
    1659           92620 :                         internal_function->return_reference = 0;
    1660                 :                 }
    1661          290840 :                 if (ptr->flags) {
    1662          106700 :                         if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
    1663             660 :                                 if (ptr->flags != ZEND_ACC_DEPRECATED || scope) {
    1664               0 :                                         zend_error(error_type, "Invalid access level for %s%s%s() - access must be exactly one of public, protected or private", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
    1665                 :                                 }
    1666             660 :                                 internal_function->fn_flags = ZEND_ACC_PUBLIC | ptr->flags;
    1667                 :                         } else {
    1668          106040 :                                 internal_function->fn_flags = ptr->flags;
    1669                 :                         }
    1670                 :                 } else {
    1671          184140 :                         internal_function->fn_flags = ZEND_ACC_PUBLIC;
    1672                 :                 }
    1673          290840 :                 if (ptr->flags & ZEND_ACC_ABSTRACT) {
    1674            5500 :                         if (scope) {
    1675                 :                                 /* This is a class that must be abstract itself. Here we set the check info. */
    1676            5500 :                                 scope->ce_flags |= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
    1677            5500 :                                 if (!(scope->ce_flags & ZEND_ACC_INTERFACE)) {
    1678                 :                                         /* Since the class is not an interface it needs to be declared as a abstract class. */
    1679                 :                                         /* Since here we are handling internal functions only we can add the keyword flag. */
    1680                 :                                         /* This time we set the flag for the keyword 'abstratc'. */
    1681             440 :                                         scope->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
    1682                 :                                 }
    1683                 :                         }
    1684            5500 :                         if (ptr->flags & ZEND_ACC_STATIC && (!scope || !(scope->ce_flags & ZEND_ACC_INTERFACE))) {
    1685               0 :                                 zend_error(error_type, "Static function %s%s%s() cannot be abstract", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
    1686                 :                         }
    1687                 :                 } else {
    1688          285340 :                         if (scope && (scope->ce_flags & ZEND_ACC_INTERFACE)) {
    1689               0 :                                 efree(lc_class_name);
    1690               0 :                                 zend_error(error_type, "Interface %s cannot contain non abstract method %s()", scope->name, ptr->fname);
    1691               0 :                                 return FAILURE;
    1692                 :                         }
    1693          285340 :                         if (!internal_function->handler) {
    1694               0 :                                 if (scope) {
    1695               0 :                                         efree(lc_class_name);
    1696                 :                                 }
    1697               0 :                                 zend_error(error_type, "Method %s%s%s() cannot be a NULL function", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
    1698               0 :                                 zend_unregister_functions(functions, count, target_function_table TSRMLS_CC);
    1699               0 :                                 return FAILURE;
    1700                 :                         }
    1701                 :                 }
    1702          290840 :                 fname_len = strlen(ptr->fname);
    1703          290840 :                 lowercase_name = do_alloca(fname_len+1);
    1704          290840 :                 zend_str_tolower_copy(lowercase_name, ptr->fname, fname_len);
    1705          290840 :                 if (zend_hash_add(target_function_table, lowercase_name, fname_len+1, &function, sizeof(zend_function), (void**)&reg_function) == FAILURE) {
    1706               0 :                         unload=1;
    1707                 :                         free_alloca(lowercase_name);
    1708               0 :                         break;
    1709                 :                 }
    1710          290840 :                 if (scope) {
    1711                 :                         /* Look for ctor, dtor, clone
    1712                 :                          * If it's an old-style constructor, store it only if we don't have
    1713                 :                          * a constructor already.
    1714                 :                          */
    1715          135960 :                         if ((fname_len == class_name_len) && !memcmp(lowercase_name, lc_class_name, class_name_len+1) && !ctor) {
    1716               0 :                                 ctor = reg_function;
    1717          143660 :                         } else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) {
    1718            7700 :                                 ctor = reg_function;
    1719          128700 :                         } else if ((fname_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME))) {
    1720             440 :                                 dtor = reg_function;
    1721             440 :                                 if (internal_function->num_args) {
    1722               0 :                                         zend_error(error_type, "Destructor %s::%s() cannot take arguments", scope->name, ptr->fname);
    1723                 :                                 }
    1724          129140 :                         } else if ((fname_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME))) {
    1725            1320 :                                 clone = reg_function;
    1726          126500 :                         } else if ((fname_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME))) {
    1727               0 :                                 __call = reg_function;
    1728          130020 :                         } else if ((fname_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME))) {
    1729            3520 :                                 __tostring = reg_function;
    1730          122980 :                         } else if ((fname_len == sizeof(ZEND_GET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME))) {
    1731               0 :                                 __get = reg_function;
    1732          122980 :                         } else if ((fname_len == sizeof(ZEND_SET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME))) {
    1733               0 :                                 __set = reg_function;
    1734          122980 :                         } else if ((fname_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME))) {
    1735               0 :                                 __unset = reg_function;
    1736          122980 :                         } else if ((fname_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME))) {
    1737               0 :                                 __isset = reg_function;
    1738                 :                         } else {
    1739          122980 :                                 reg_function = NULL;
    1740                 :                         }
    1741          135960 :                         if (reg_function) {
    1742           12980 :                                 zend_check_magic_method_implementation(scope, reg_function, error_type TSRMLS_CC);
    1743                 :                         }
    1744                 :                 }
    1745          290840 :                 ptr++;
    1746          290840 :                 count++;
    1747                 :                 free_alloca(lowercase_name);
    1748                 :         }
    1749           14960 :         if (unload) { /* before unloading, display all remaining bad function in the module */
    1750               0 :                 if (scope) {
    1751               0 :                         efree(lc_class_name);
    1752                 :                 }
    1753               0 :                 while (ptr->fname) {
    1754               0 :                         if (zend_hash_exists(target_function_table, ptr->fname, strlen(ptr->fname)+1)) {
    1755               0 :                                 zend_error(error_type, "Function registration failed - duplicate name - %s%s%s", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
    1756                 :                         }
    1757               0 :                         ptr++;
    1758                 :                 }
    1759               0 :                 zend_unregister_functions(functions, count, target_function_table TSRMLS_CC);
    1760               0 :                 return FAILURE;
    1761                 :         }
    1762           14960 :         if (scope) {
    1763           12760 :                 scope->constructor = ctor;
    1764           12760 :                 scope->destructor = dtor;
    1765           12760 :                 scope->clone = clone;
    1766           12760 :                 scope->__call = __call;
    1767           12760 :                 scope->__tostring = __tostring;
    1768           12760 :                 scope->__get = __get;
    1769           12760 :                 scope->__set = __set;
    1770           12760 :                 scope->__unset = __unset;
    1771           12760 :                 scope->__isset = __isset;
    1772           12760 :                 if (ctor) {
    1773            7700 :                         ctor->common.fn_flags |= ZEND_ACC_CTOR;
    1774            7700 :                         if (ctor->common.fn_flags & ZEND_ACC_STATIC) {
    1775               0 :                                 zend_error(error_type, "Constructor %s::%s() cannot be static", scope->name, ctor->common.function_name);
    1776                 :                         }
    1777            7700 :                         ctor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1778                 :                 }
    1779           12760 :                 if (dtor) {
    1780             440 :                         dtor->common.fn_flags |= ZEND_ACC_DTOR;
    1781             440 :                         if (dtor->common.fn_flags & ZEND_ACC_STATIC) {
    1782               0 :                                 zend_error(error_type, "Destructor %s::%s() cannot be static", scope->name, dtor->common.function_name);
    1783                 :                         }
    1784             440 :                         dtor->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1785                 :                 }
    1786           12760 :                 if (clone) {
    1787            1320 :                         clone->common.fn_flags |= ZEND_ACC_CLONE;
    1788            1320 :                         if (clone->common.fn_flags & ZEND_ACC_STATIC) {
    1789               0 :                                 zend_error(error_type, "Constructor %s::%s() cannot be static", scope->name, clone->common.function_name);
    1790                 :                         }
    1791            1320 :                         clone->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1792                 :                 }
    1793           12760 :                 if (__call) {
    1794               0 :                         if (__call->common.fn_flags & ZEND_ACC_STATIC) {
    1795               0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __call->common.function_name);
    1796                 :                         }
    1797               0 :                         __call->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1798                 :                 }
    1799           12760 :                 if (__tostring) {
    1800            3520 :                         if (__tostring->common.fn_flags & ZEND_ACC_STATIC) {
    1801               0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __tostring->common.function_name);
    1802                 :                         }
    1803            3520 :                         __tostring->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1804                 :                 }
    1805           12760 :                 if (__get) {
    1806               0 :                         if (__get->common.fn_flags & ZEND_ACC_STATIC) {
    1807               0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __get->common.function_name);
    1808                 :                         }
    1809               0 :                         __get->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1810                 :                 }
    1811           12760 :                 if (__set) {
    1812               0 :                         if (__set->common.fn_flags & ZEND_ACC_STATIC) {
    1813               0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __set->common.function_name);
    1814                 :                         }
    1815               0 :                         __set->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1816                 :                 }
    1817           12760 :                 if (__unset) {
    1818               0 :                         if (__unset->common.fn_flags & ZEND_ACC_STATIC) {
    1819               0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __unset->common.function_name);
    1820                 :                         }
    1821               0 :                         __unset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1822                 :                 }
    1823           12760 :                 if (__isset) {
    1824               0 :                         if (__isset->common.fn_flags & ZEND_ACC_STATIC) {
    1825               0 :                                 zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __isset->common.function_name);
    1826                 :                         }
    1827               0 :                         __isset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC;
    1828                 :                 }
    1829           12760 :                 efree(lc_class_name);
    1830                 :         }
    1831           14960 :         return SUCCESS;
    1832                 : }
    1833                 : 
    1834                 : /* count=-1 means erase all functions, otherwise,
    1835                 :  * erase the first count functions
    1836                 :  */
    1837                 : ZEND_API void zend_unregister_functions(zend_function_entry *functions, int count, HashTable *function_table TSRMLS_DC)
    1838            1971 : {
    1839            1971 :         zend_function_entry *ptr = functions;
    1840            1971 :         int i=0;
    1841            1971 :         HashTable *target_function_table = function_table;
    1842                 : 
    1843            1971 :         if (!target_function_table) {
    1844            1971 :                 target_function_table = CG(function_table);
    1845                 :         }
    1846          148263 :         while (ptr->fname) {
    1847          144321 :                 if (count!=-1 && i>=count) {
    1848               0 :                         break;
    1849                 :                 }
    1850                 : #if 0
    1851                 :                 zend_printf("Unregistering %s()\n", ptr->fname);
    1852                 : #endif
    1853          144321 :                 zend_hash_del(target_function_table, ptr->fname, strlen(ptr->fname)+1);
    1854          144321 :                 ptr++;
    1855          144321 :                 i++;
    1856                 :         }
    1857            1971 : }
    1858                 : 
    1859                 : 
    1860                 : ZEND_API int zend_startup_module(zend_module_entry *module)
    1861               0 : {
    1862                 :         TSRMLS_FETCH();
    1863                 : 
    1864               0 :         if ((module = zend_register_internal_module(module TSRMLS_CC)) != NULL &&
    1865                 :             zend_startup_module_ex(module TSRMLS_CC) == SUCCESS) {
    1866               0 :                 return SUCCESS;
    1867                 :         }
    1868               0 :         return FAILURE;
    1869                 : }
    1870                 : 
    1871                 : 
    1872                 : ZEND_API int zend_get_module_started(char *module_name)
    1873               0 : {
    1874                 :         zend_module_entry *module;
    1875                 : 
    1876               0 :         return (zend_hash_find(&module_registry, module_name, strlen(module_name)+1, (void**)&module) == SUCCESS && module->module_started) ? SUCCESS : FAILURE;
    1877                 : }
    1878                 : 
    1879                 : 
    1880                 : void module_destructor(zend_module_entry *module)
    1881            2189 : {
    1882                 :         TSRMLS_FETCH();
    1883                 : 
    1884            2189 :         if (module->type == MODULE_TEMPORARY) {
    1885               0 :                 zend_clean_module_rsrc_dtors(module->module_number TSRMLS_CC);
    1886               0 :                 clean_module_constants(module->module_number TSRMLS_CC);
    1887                 :         }
    1888                 : 
    1889            2189 :         if (module->module_started && module->module_shutdown_func) {
    1890                 : #if 0
    1891                 :                 zend_printf("%s:  Module shutdown\n", module->name);
    1892                 : #endif
    1893            1751 :                 module->module_shutdown_func(module->type, module->module_number TSRMLS_CC);
    1894                 :         }
    1895                 :         
    1896                 :         /* Deinitilaise module globals */
    1897            2189 :         if (module->globals_size) {
    1898                 : #ifdef ZTS
    1899                 :                 ts_free_id(*module->globals_id_ptr);
    1900                 : #else
    1901            1095 :                 if (module->globals_dtor) {
    1902             219 :                         module->globals_dtor(module->globals_ptr TSRMLS_CC);
    1903                 :                 }
    1904                 : #endif
    1905                 :         }
    1906                 : 
    1907            2189 :         module->module_started=0;
    1908            2189 :         if (module->functions) {
    1909            1971 :                 zend_unregister_functions(module->functions, -1, NULL TSRMLS_CC);
    1910                 :         }
    1911                 : 
    1912                 : #if HAVE_LIBDL || defined(HAVE_MACH_O_DYLD_H)
    1913                 : #if !(defined(NETWARE) && defined(APACHE_1_BUILD))
    1914            2189 :         if (module->handle) {
    1915               0 :                 DL_UNLOAD(module->handle);
    1916                 :         }
    1917                 : #endif
    1918                 : #endif
    1919            2189 : }
    1920                 : 
    1921                 : 
    1922                 : /* call request startup for all modules */
    1923                 : int module_registry_request_startup(zend_module_entry *module TSRMLS_DC)
    1924            2189 : {
    1925            2189 :         if (module->request_startup_func) {
    1926                 : #if 0
    1927                 :                 zend_printf("%s:  Request startup\n", module->name);
    1928                 : #endif
    1929            1095 :                 if (module->request_startup_func(module->type, module->module_number TSRMLS_CC)==FAILURE) {
    1930               0 :                         zend_error(E_WARNING, "request_startup() for %s module failed", module->name);
    1931               0 :                         exit(1);
    1932                 :                 }
    1933                 :         }
    1934            2189 :         return 0;
    1935                 : }
    1936                 : 
    1937                 : 
    1938                 : /* call request shutdown for all modules */
    1939                 : int module_registry_cleanup(zend_module_entry *module TSRMLS_DC)
    1940            2189 : {
    1941            2189 :         if (module->request_shutdown_func) {
    1942                 : #if 0
    1943                 :                 zend_printf("%s:  Request shutdown\n", module->name);
    1944                 : #endif
    1945            1095 :                 module->request_shutdown_func(module->type, module->module_number TSRMLS_CC);
    1946                 :         }
    1947            2189 :         return 0;
    1948                 : }
    1949                 : 
    1950                 : int module_registry_unload_temp(zend_module_entry *module TSRMLS_DC)
    1951             219 : {
    1952             219 :         return (module->type == MODULE_TEMPORARY) ? ZEND_HASH_APPLY_REMOVE : ZEND_HASH_APPLY_STOP;
    1953                 : }
    1954                 : 
    1955                 : 
    1956                 : /* return the next free module number */
    1957                 : int zend_next_free_module(void)
    1958            2199 : {
    1959            2199 :         return ++module_count;
    1960                 : }
    1961                 : 
    1962                 : static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, zend_uint ce_flags TSRMLS_DC)
    1963           18920 : {
    1964           18920 :         zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
    1965           18920 :         char *lowercase_name = malloc(orig_class_entry->name_length + 1);
    1966           18920 :         *class_entry = *orig_class_entry;
    1967                 : 
    1968           18920 :         class_entry->type = ZEND_INTERNAL_CLASS;
    1969           18920 :         zend_initialize_class_data(class_entry, 0 TSRMLS_CC);
    1970           18920 :         class_entry->ce_flags = ce_flags;
    1971           18920 :         class_entry->module = EG(current_module);
    1972                 : 
    1973           18920 :         if (class_entry->builtin_functions) {
    1974           12760 :                 zend_register_functions(class_entry, class_entry->builtin_functions, &class_entry->function_table, MODULE_PERSISTENT TSRMLS_CC);
    1975                 :         }
    1976                 : 
    1977           18920 :         zend_str_tolower_copy(lowercase_name, orig_class_entry->name, class_entry->name_length);
    1978           18920 :         zend_hash_update(CG(class_table), lowercase_name, class_entry->name_length+1, &class_entry, sizeof(zend_class_entry *), NULL);
    1979           18920 :         free(lowercase_name);
    1980           18920 :         return class_entry;
    1981                 : }
    1982                 : 
    1983                 : /* If parent_ce is not NULL then it inherits from parent_ce
    1984                 :  * If parent_ce is NULL and parent_name isn't then it looks for the parent and inherits from it
    1985                 :  * If both parent_ce and parent_name are NULL it does a regular class registration
    1986                 :  * If parent_name is specified but not found NULL is returned
    1987                 :  */
    1988                 : ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name TSRMLS_DC)
    1989           12540 : {
    1990                 :         zend_class_entry *register_class;
    1991                 : 
    1992           12540 :         if (!parent_ce && parent_name) {
    1993                 :                 zend_class_entry **pce;
    1994               0 :                 if (zend_hash_find(CG(class_table), parent_name, strlen(parent_name)+1, (void **) &pce)==FAILURE) {
    1995               0 :                         return NULL;
    1996                 :                 } else {
    1997               0 :                         parent_ce = *pce;
    1998                 :                 }
    1999                 :         }
    2000                 : 
    2001           12540 :         register_class = zend_register_internal_class(class_entry TSRMLS_CC);
    2002                 : 
    2003           12540 :         if (parent_ce) {
    2004           10120 :                 zend_do_inheritance(register_class, parent_ce TSRMLS_CC);
    2005                 :         }
    2006           12540 :         return register_class;
    2007                 : }
    2008                 : 
    2009                 : ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int num_interfaces, ...)
    2010            7260 : {
    2011                 :         zend_class_entry *interface_entry;
    2012                 :         va_list interface_list;
    2013            7260 :         va_start(interface_list, num_interfaces);
    2014                 : 
    2015           22660 :         while (num_interfaces--) {
    2016            8140 :                 interface_entry = va_arg(interface_list, zend_class_entry *);
    2017            8140 :                 zend_do_implement_interface(class_entry, interface_entry TSRMLS_CC);
    2018                 :         }
    2019                 :         
    2020            7260 :         va_end(interface_list);
    2021            7260 : }
    2022                 : 
    2023                 : /* A class that contains at least one abstract method automatically becomes an abstract class.
    2024                 :  */
    2025                 : ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_class_entry TSRMLS_DC)
    2026           16280 : {
    2027           16280 :         return do_register_internal_class(orig_class_entry, 0 TSRMLS_CC);
    2028                 : }
    2029                 : 
    2030                 : ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *orig_class_entry TSRMLS_DC)
    2031            2640 : {
    2032            2640 :         return do_register_internal_class(orig_class_entry, ZEND_ACC_INTERFACE TSRMLS_CC);
    2033                 : }
    2034                 : 
    2035                 : ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
    2036                 :                                   zend_bool is_ref, int num_symbol_tables, ...)
    2037               0 : {
    2038                 :         HashTable  *symbol_table;
    2039                 :         va_list     symbol_table_list;
    2040                 : 
    2041               0 :         if (num_symbol_tables <= 0) return FAILURE;
    2042                 : 
    2043               0 :         symbol->is_ref = is_ref;
    2044                 : 
    2045               0 :         va_start(symbol_table_list, num_symbol_tables);
    2046               0 :         while (num_symbol_tables-- > 0) {
    2047               0 :                 symbol_table = va_arg(symbol_table_list, HashTable *);
    2048               0 :                 zend_hash_update(symbol_table, name, name_length + 1, &symbol, sizeof(zval *), NULL);
    2049               0 :                 zval_add_ref(&symbol);
    2050                 :         }
    2051               0 :         va_end(symbol_table_list);
    2052               0 :         return SUCCESS;
    2053                 : }
    2054                 : 
    2055                 : 
    2056                 : 
    2057                 : 
    2058                 : /* Disabled functions support */
    2059                 : 
    2060                 : ZEND_API ZEND_FUNCTION(display_disabled_function)
    2061               0 : {
    2062               0 :         zend_error(E_WARNING, "%s() has been disabled for security reasons", get_active_function_name(TSRMLS_C));
    2063               0 : }
    2064                 : 
    2065                 : 
    2066                 : static zend_function_entry disabled_function[] =  {
    2067                 :         ZEND_FE(display_disabled_function,                      NULL)
    2068                 :         { NULL, NULL, NULL }
    2069                 : };
    2070                 : 
    2071                 : 
    2072                 : ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC)
    2073               0 : {
    2074               0 :         if (zend_hash_del(CG(function_table), function_name, function_name_length+1)==FAILURE) {
    2075               0 :                 return FAILURE;
    2076                 :         }
    2077               0 :         disabled_function[0].fname = function_name;
    2078               0 :         return zend_register_functions(NULL, disabled_function, CG(function_table), MODULE_PERSISTENT TSRMLS_CC);
    2079                 : }
    2080                 : 
    2081                 : static zend_object_value display_disabled_class(zend_class_entry *class_type TSRMLS_DC)
    2082               0 : {
    2083                 :         zend_object_value retval;
    2084                 :         zend_object *intern;
    2085               0 :         retval = zend_objects_new(&intern, class_type TSRMLS_CC);
    2086               0 :         ALLOC_HASHTABLE(intern->properties);
    2087               0 :         zend_hash_init(intern->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
    2088               0 :         zend_error(E_WARNING, "%s() has been disabled for security reasons", class_type->name);
    2089               0 :         return retval;
    2090                 : }
    2091                 : 
    2092                 : static zend_function_entry disabled_class_new[] =  {
    2093                 :         { NULL, NULL, NULL }
    2094                 : };
    2095                 : 
    2096                 : ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC)
    2097               0 : {
    2098                 :         zend_class_entry disabled_class;
    2099                 : 
    2100               0 :         zend_str_tolower(class_name, class_name_length);
    2101               0 :         if (zend_hash_del(CG(class_table), class_name, class_name_length+1)==FAILURE) {
    2102               0 :                 return FAILURE;
    2103                 :         }
    2104               0 :         INIT_CLASS_ENTRY(disabled_class, class_name, disabled_class_new);
    2105               0 :         disabled_class.create_object = display_disabled_class;
    2106               0 :         disabled_class.name_length = class_name_length;
    2107               0 :         zend_register_internal_class(&disabled_class TSRMLS_CC);
    2108               0 :         return SUCCESS;
    2109                 : }
    2110                 : 
    2111                 : static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, zend_class_entry *ce_org, zval *callable, zend_class_entry **ce_ptr, zend_function **fptr_ptr TSRMLS_DC)
    2112              12 : {
    2113                 :         int retval;
    2114                 :         char *lcname, *lmname, *colon;
    2115                 :         int clen, mlen;
    2116                 :         zend_function *fptr;
    2117                 :         zend_class_entry **pce;
    2118                 :         HashTable *ftable;
    2119                 : 
    2120              12 :         *ce_ptr = NULL;
    2121              12 :         *fptr_ptr = NULL;
    2122                 : 
    2123              12 :         if ((colon = strstr(Z_STRVAL_P(callable), "::")) != NULL) {
    2124               0 :                 clen = colon - Z_STRVAL_P(callable);
    2125               0 :                 mlen = Z_STRLEN_P(callable) - clen - 2;
    2126               0 :                 lcname = zend_str_tolower_dup(Z_STRVAL_P(callable), clen);
    2127                 :                 /* caution: lcname is not '\0' terminated */
    2128               0 :                 if (clen == sizeof("self") - 1 && memcmp(lcname, "self", sizeof("self") - 1) == 0) {
    2129               0 :                         *ce_ptr = EG(scope);
    2130               0 :                 } else if (clen == sizeof("parent") - 1 && memcmp(lcname, "parent", sizeof("parent") - 1) == 0 && EG(active_op_array)->scope) {
    2131               0 :                         *ce_ptr = EG(scope) ? EG(scope)->parent : NULL;
    2132               0 :                 } else if (zend_lookup_class(Z_STRVAL_P(callable), clen, &pce TSRMLS_CC) == SUCCESS) {
    2133               0 :                         *ce_ptr = *pce;
    2134                 :                 }
    2135               0 :                 efree(lcname);
    2136               0 :                 if (!*ce_ptr) {
    2137               0 :                         return 0;
    2138                 :                 }
    2139               0 :                 ftable = &(*ce_ptr)->function_table;
    2140               0 :                 if (ce_org && !instanceof_function(ce_org, *ce_ptr TSRMLS_CC)) {
    2141               0 :                         return 0;
    2142                 :                 }
    2143               0 :                 lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + clen + 2, mlen);
    2144                 :         } else {
    2145              12 :                 mlen = Z_STRLEN_P(callable);
    2146              12 :                 lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), mlen);
    2147              12 :                 if (ce_org) {
    2148               0 :                         ftable = &ce_org->function_table;
    2149               0 :                         *ce_ptr = ce_org;
    2150                 :                 } else {
    2151              12 :                         ftable = EG(function_table);
    2152                 :                 }
    2153                 :         }
    2154                 : 
    2155              12 :         retval = zend_hash_find(ftable, lmname, mlen+1, (void**)&fptr) == SUCCESS ? 1 : 0;
    2156                 : 
    2157              12 :         if (!retval) {
    2158               0 :                 if (*zobj_ptr_ptr && *ce_ptr && (*ce_ptr)->__call != 0) {
    2159               0 :                         retval = (*ce_ptr)->__call != NULL;
    2160               0 :                         *fptr_ptr = (*ce_ptr)->__call;
    2161                 :                 }
    2162                 :         } else {
    2163              12 :                 *fptr_ptr = fptr;
    2164              12 :                 if (*ce_ptr) {
    2165               0 :                         if (!*zobj_ptr_ptr && !(fptr->common.fn_flags & ZEND_ACC_STATIC)) {
    2166               0 :                                 if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) {
    2167               0 :                                         retval = 0;
    2168                 :                                 } else {
    2169               0 :                                         if (EG(This) && instanceof_function(Z_OBJCE_P(EG(This)), *ce_ptr TSRMLS_CC)) {
    2170               0 :                                                 *zobj_ptr_ptr = &EG(This);
    2171               0 :                                                 zend_error(E_STRICT, "Non-static method %s::%s() cannot be called statically, assuming $this from compatible context %s", (*ce_ptr)->name, fptr->common.function_name, Z_OBJCE_P(EG(This))->name);
    2172                 :                                         } else {
    2173               0 :                                                 zend_error(E_STRICT, "Non-static method %s::%s() cannot be called statically", (*ce_ptr)->name, fptr->common.function_name);
    2174                 :                                         }
    2175                 :                                 }
    2176                 :                         }
    2177               0 :                         if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
    2178               0 :                                 if (fptr->op_array.fn_flags & ZEND_ACC_PRIVATE) {
    2179               0 :                                         if (!zend_check_private(fptr, *zobj_ptr_ptr ? Z_OBJCE_PP(*zobj_ptr_ptr) : EG(scope), lmname, mlen TSRMLS_CC)) {
    2180               0 :                                                 retval = 0;
    2181                 :                                         }
    2182               0 :                                 } else if ((fptr->common.fn_flags & ZEND_ACC_PROTECTED)) {
    2183               0 :                                         if (!zend_check_protected(fptr->common.scope, EG(scope))) {
    2184               0 :                                                 retval = 0;
    2185                 :                                         }
    2186                 :                                 }
    2187                 :                         }
    2188                 :                 }
    2189                 :         }
    2190              12 :         efree(lmname);
    2191              12 :         return retval;
    2192                 : }
    2193                 : 
    2194                 : ZEND_API zend_bool zend_is_callable_ex(zval *callable, uint check_flags, char **callable_name, int *callable_name_len, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval ***zobj_ptr_ptr TSRMLS_DC)
    2195              12 : {
    2196                 :         char *lcname;
    2197              12 :         zend_bool retval = 0; 
    2198                 :         int callable_name_len_local;
    2199                 :         zend_class_entry *ce_local, **pce;
    2200                 :         zend_function *fptr_local;
    2201                 :         zval **zobj_ptr_local;
    2202                 : 
    2203              12 :         if (callable_name) {
    2204               1 :                 *callable_name = NULL;
    2205                 :         }
    2206              12 :         if (callable_name_len == NULL) {
    2207              12 :                 callable_name_len = &callable_name_len_local;
    2208                 :         }
    2209              12 :         if (ce_ptr == NULL) {
    2210              12 :                 ce_ptr = &ce_local;
    2211                 :         }
    2212              12 :         if (fptr_ptr == NULL) {
    2213              12 :                 fptr_ptr = &fptr_local;
    2214                 :         }
    2215              12 :         if (zobj_ptr_ptr == NULL) {
    2216              12 :                 zobj_ptr_ptr = &zobj_ptr_local;
    2217                 :         }
    2218              12 :         *ce_ptr = NULL;
    2219              12 :         *fptr_ptr = NULL;
    2220              12 :         *zobj_ptr_ptr = NULL;
    2221                 : 
    2222              12 :         switch (Z_TYPE_P(callable)) {
    2223                 :                 case IS_STRING:
    2224              12 :                         if (callable_name) {
    2225               1 :                                 *callable_name = estrndup(Z_STRVAL_P(callable), Z_STRLEN_P(callable));
    2226               1 :                                 *callable_name_len = Z_STRLEN_P(callable);
    2227                 :                         }
    2228              12 :                         if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
    2229               0 :                                 return 1;
    2230                 :                         }
    2231                 :                         
    2232              12 :                         retval = zend_is_callable_check_func(check_flags|IS_CALLABLE_CHECK_IS_STATIC, zobj_ptr_ptr, NULL, callable, ce_ptr, fptr_ptr TSRMLS_CC);
    2233              12 :                         break;
    2234                 : 
    2235                 :                 case IS_ARRAY:
    2236                 :                         {
    2237               0 :                                 zend_class_entry *ce = NULL;
    2238                 :                                 zval **method;
    2239                 :                                 zval **obj;
    2240                 : 
    2241               0 :                                 if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2 &&
    2242                 :                                         zend_hash_index_find(Z_ARRVAL_P(callable), 0, (void **) &obj) == SUCCESS &&
    2243                 :                                         zend_hash_index_find(Z_ARRVAL_P(callable), 1, (void **) &method) == SUCCESS &&
    2244                 :                                         (Z_TYPE_PP(obj) == IS_OBJECT || Z_TYPE_PP(obj) == IS_STRING) &&
    2245                 :                                         Z_TYPE_PP(method) == IS_STRING) {
    2246                 : 
    2247               0 :                                         if (Z_TYPE_PP(obj) == IS_STRING) {
    2248               0 :                                                 if (callable_name) {
    2249                 :                                                         char *ptr;
    2250                 : 
    2251               0 :                                                         *callable_name_len = Z_STRLEN_PP(obj) + Z_STRLEN_PP(method) + sizeof("::") - 1;
    2252               0 :                                                         ptr = *callable_name = emalloc(*callable_name_len + 1);
    2253               0 :                                                         memcpy(ptr, Z_STRVAL_PP(obj), Z_STRLEN_PP(obj));
    2254               0 :                                                         ptr += Z_STRLEN_PP(obj);
    2255               0 :                                                         memcpy(ptr, "::", sizeof("::") - 1);
    2256               0 :                                                         ptr += sizeof("::") - 1;
    2257               0 :                                                         memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1);
    2258                 :                                                 }
    2259                 : 
    2260               0 :                                                 if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
    2261               0 :                                                         return 1;
    2262                 :                                                 }
    2263                 : 
    2264               0 :                                                 lcname = zend_str_tolower_dup(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj));
    2265               0 :                                                 if (Z_STRLEN_PP(obj) == sizeof("self") - 1 && memcmp(lcname, "self", sizeof("self")) == 0 && EG(active_op_array)) {
    2266               0 :                                                         ce = EG(active_op_array)->scope;
    2267               0 :                                                 } else if (Z_STRLEN_PP(obj) == sizeof("parent") - 1 && memcmp(lcname, "parent", sizeof("parent")) == 0 && EG(active_op_array) && EG(active_op_array)->scope) {
    2268               0 :                                                         ce = EG(active_op_array)->scope->parent;
    2269               0 :                                                 } else if (zend_lookup_class(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), &pce TSRMLS_CC) == SUCCESS) {
    2270               0 :                                                         ce = *pce;
    2271                 :                                                 }
    2272               0 :                                                 efree(lcname);
    2273                 :                                         } else {
    2274               0 :                                                 ce = Z_OBJCE_PP(obj); /* TBFixed: what if it's overloaded? */
    2275                 : 
    2276               0 :                                                 *zobj_ptr_ptr = obj;
    2277                 : 
    2278               0 :                                                 if (callable_name) {
    2279                 :                                                         char *ptr;
    2280                 : 
    2281               0 :                                                         *callable_name_len = ce->name_length + Z_STRLEN_PP(method) + sizeof("::") - 1;
    2282               0 :                                                         ptr = *callable_name = emalloc(*callable_name_len + 1);
    2283               0 :                                                         memcpy(ptr, ce->name, ce->name_length);
    2284               0 :                                                         ptr += ce->name_length;
    2285               0 :                                                         memcpy(ptr, "::", sizeof("::") - 1);
    2286               0 :                                                         ptr += sizeof("::") - 1;
    2287               0 :                                                         memcpy(ptr, Z_STRVAL_PP(method), Z_STRLEN_PP(method) + 1);
    2288                 :                                                 }
    2289                 : 
    2290               0 :                                                 if (check_flags & IS_CALLABLE_CHECK_SYNTAX_ONLY) {
    2291               0 :                                                         *ce_ptr = ce;
    2292               0 :                                                         return 1;
    2293                 :                                                 }
    2294                 :                                         }
    2295                 : 
    2296               0 :                                         if (ce) {
    2297               0 :                                                 retval = zend_is_callable_check_func(check_flags, zobj_ptr_ptr, ce, *method, ce_ptr, fptr_ptr TSRMLS_CC);
    2298                 :                                         }
    2299               0 :                                 } else if (callable_name) {
    2300               0 :                                         *callable_name = estrndup("Array", sizeof("Array")-1);
    2301               0 :                                         *callable_name_len = sizeof("Array") - 1;
    2302                 :                                 }
    2303               0 :                                 *ce_ptr = ce;
    2304                 :                         }
    2305               0 :                         break;
    2306                 : 
    2307                 :                 default:
    2308               0 :                         if (callable_name) {
    2309                 :                                 zval expr_copy;
    2310                 :                                 int use_copy;
    2311                 : 
    2312               0 :                                 zend_make_printable_zval(callable, &expr_copy, &use_copy);
    2313               0 :                                 *callable_name = estrndup(Z_STRVAL(expr_copy), Z_STRLEN(expr_copy));
    2314               0 :                                 *callable_name_len = Z_STRLEN(expr_copy);
    2315               0 :                                 zval_dtor(&expr_copy);
    2316                 :                         }
    2317                 :                         break;
    2318                 :         }
    2319                 : 
    2320              12 :         return retval;
    2321                 : }
    2322                 : 
    2323                 : 
    2324                 : ZEND_API zend_bool zend_is_callable(zval *callable, uint check_flags, char **callable_name)
    2325              12 : {
    2326                 :         TSRMLS_FETCH();
    2327                 : 
    2328              12 :         return zend_is_callable_ex(callable, check_flags, callable_name, NULL, NULL, NULL, NULL TSRMLS_CC);
    2329                 : }
    2330                 : 
    2331                 : 
    2332                 : ZEND_API zend_bool zend_make_callable(zval *callable, char **callable_name TSRMLS_DC)
    2333               0 : {
    2334                 :         zend_class_entry *ce;
    2335                 :         zend_function *fptr;
    2336                 :         zval **zobj_ptr;
    2337                 : 
    2338               0 :         if (zend_is_callable_ex(callable, 0, callable_name, NULL, &ce, &fptr, &zobj_ptr TSRMLS_CC)) {
    2339               0 :                 if (Z_TYPE_P(callable) == IS_STRING && ce) {
    2340               0 :                         zval_dtor(callable);
    2341               0 :                         array_init(callable);
    2342               0 :                         add_next_index_string(callable, ce->name, 1);
    2343               0 :                         add_next_index_string(callable, fptr->common.function_name, 1);
    2344                 :                 }
    2345               0 :                 return 1;
    2346                 :         }
    2347               0 :         return 0;
    2348                 : }
    2349                 : 
    2350                 : 
    2351                 : ZEND_API int zend_fcall_info_init(zval *callable, zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC)
    2352               0 : {
    2353                 :         zend_class_entry *ce;
    2354                 :         zend_function    *func;
    2355                 :         zval             **obj;
    2356                 : 
    2357               0 :         if (!zend_is_callable_ex(callable, IS_CALLABLE_STRICT, NULL, NULL, &ce, &func, &obj TSRMLS_CC)) {
    2358               0 :                 return FAILURE;
    2359                 :         }
    2360                 : 
    2361               0 :         fci->size = sizeof(*fci);
    2362               0 :         fci->function_table = ce ? &ce->function_table : EG(function_table);
    2363               0 :         fci->object_pp = obj;
    2364               0 :         fci->function_name = NULL;
    2365               0 :         fci->retval_ptr_ptr = NULL;
    2366               0 :         fci->param_count = 0;
    2367               0 :         fci->params = NULL;
    2368               0 :         fci->no_separation = 1;
    2369               0 :         fci->symbol_table = NULL;
    2370                 : 
    2371               0 :         fcc->initialized = 1;
    2372               0 :         fcc->function_handler = func;
    2373               0 :         fcc->calling_scope = ce;
    2374               0 :         fcc->object_pp = obj;
    2375                 : 
    2376               0 :         return SUCCESS;
    2377                 : }
    2378                 : 
    2379                 : 
    2380                 : ZEND_API void zend_fcall_info_args_clear(zend_fcall_info *fci, int free_mem)
    2381               0 : {
    2382               0 :         if (fci->params) {
    2383               0 :                 while (fci->param_count) {
    2384               0 :                         zval_ptr_dtor(fci->params[--fci->param_count]);
    2385                 :                 }
    2386               0 :                 if (free_mem) {
    2387               0 :                         efree(fci->params);
    2388               0 :                         fci->params = NULL;
    2389                 :                 }
    2390                 :         }
    2391               0 :         fci->param_count = 0;
    2392               0 : }
    2393                 : 
    2394                 : ZEND_API void zend_fcall_info_args_save(zend_fcall_info *fci, int *param_count, zval ****params)
    2395               0 : {
    2396               0 :         *param_count = fci->param_count;
    2397               0 :         *params = fci->params;
    2398               0 :         fci->param_count = 0;
    2399               0 :         fci->params = NULL;
    2400               0 : }
    2401                 : 
    2402                 : ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count, zval ***params)
    2403               0 : {
    2404               0 :         zend_fcall_info_args_clear(fci, 1);
    2405               0 :         fci->param_count = param_count;
    2406               0 :         fci->params = params;
    2407               0 : }
    2408                 : 
    2409                 : ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC)
    2410               0 : {
    2411                 :         HashPosition pos;
    2412                 :         zval         **arg, ***params;
    2413                 : 
    2414               0 :         zend_fcall_info_args_clear(fci, !args);
    2415                 : 
    2416               0 :         if (!args) {
    2417               0 :                 return SUCCESS;
    2418                 :         }
    2419                 : 
    2420               0 :         if (Z_TYPE_P(args) != IS_ARRAY) {
    2421               0 :                 return FAILURE;
    2422                 :         }
    2423                 : 
    2424               0 :         fci->param_count = zend_hash_num_elements(Z_ARRVAL_P(args));
    2425               0 :         fci->params = params = (zval***)safe_emalloc(sizeof(zval**), fci->param_count, 0);
    2426                 : 
    2427               0 :         zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos);
    2428               0 :         while (zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **) &arg, &pos) == SUCCESS) {
    2429               0 :                 *params++ = arg;
    2430               0 :                 (*arg)->refcount++;
    2431               0 :                 zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos);
    2432                 :         }
    2433               0 :         return SUCCESS;
    2434                 : }
    2435                 : 
    2436                 : 
    2437                 : ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *fcc, zval **retval_ptr_ptr, zval *args TSRMLS_DC)
    2438               0 : {
    2439               0 :         zval *retval, ***org_params = NULL;
    2440               0 :         int  result, org_count = 0;
    2441                 : 
    2442               0 :         fci->retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
    2443               0 :         if (args) {
    2444               0 :                 zend_fcall_info_args_save(fci, &org_count, &org_params);
    2445               0 :                 zend_fcall_info_args(fci, args TSRMLS_CC);
    2446                 :         }
    2447               0 :         result = zend_call_function(fci, fcc TSRMLS_CC);
    2448                 :         
    2449               0 :         if (!retval_ptr_ptr && retval) {
    2450               0 :                 zval_ptr_dtor(&retval);
    2451                 :         }
    2452               0 :         if (args) {
    2453               0 :                 zend_fcall_info_args_restore(fci, org_count, org_params);
    2454                 :         }
    2455               0 :         return result;
    2456                 : }
    2457                 : 
    2458                 : 
    2459                 : ZEND_API char *zend_get_module_version(char *module_name)
    2460               0 : {
    2461                 :         zend_module_entry *module;
    2462                 : 
    2463               0 :         if (zend_hash_find(&module_registry, module_name, strlen(module_name) + 1,
    2464                 :                            (void**)&module) == FAILURE) {
    2465               0 :                 return NULL;
    2466                 :         }
    2467               0 :         return module->version;
    2468                 : }
    2469                 : 
    2470                 : 
    2471                 : ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_length, zval *property, int access_type TSRMLS_DC)
    2472           14740 : {
    2473           14740 :         return zend_declare_property_ex(ce, name, name_length, property, access_type, NULL, 0 TSRMLS_CC);
    2474                 : }
    2475                 : 
    2476                 : ZEND_API int zend_declare_property_ex(zend_class_entry *ce, char *name, int name_length, zval *property, int access_type, char *doc_comment, int doc_comment_len TSRMLS_DC)
    2477           14743 : {
    2478                 :         zend_property_info property_info;
    2479                 :         HashTable *target_symbol_table;
    2480                 : 
    2481           14743 :         if (!(access_type & ZEND_ACC_PPP_MASK)) {
    2482             220 :                 access_type |= ZEND_ACC_PUBLIC;
    2483                 :         }
    2484           14743 :         if (access_type & ZEND_ACC_STATIC) {
    2485            3740 :                 target_symbol_table = &ce->default_static_members;
    2486                 :         } else {
    2487           11003 :                 target_symbol_table = &ce->default_properties;
    2488                 :         }
    2489           14743 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2490           14740 :                 switch(Z_TYPE_P(property)) {
    2491                 :                         case IS_ARRAY:
    2492                 :                         case IS_CONSTANT_ARRAY:
    2493                 :                         case IS_OBJECT:
    2494                 :                         case IS_RESOURCE:
    2495               0 :                                 zend_error(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
    2496                 :                                 break;
    2497                 :                         default:
    2498                 :                                 break;
    2499                 :                 }
    2500                 :         }
    2501           14743 :         switch (access_type & ZEND_ACC_PPP_MASK) {
    2502                 :                 case ZEND_ACC_PRIVATE: {
    2503                 :                                 char *priv_name;
    2504                 :                                 int priv_name_length;
    2505                 : 
    2506            5943 :                                 zend_mangle_property_name(&priv_name, &priv_name_length, ce->name, ce->name_length, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
    2507            5943 :                                 zend_hash_update(target_symbol_table, priv_name, priv_name_length+1, &property, sizeof(zval *), NULL);
    2508            5943 :                                 property_info.name = priv_name;
    2509            5943 :                                 property_info.name_length = priv_name_length;
    2510                 :                         }
    2511            5943 :                         break;
    2512                 :                 case ZEND_ACC_PROTECTED: {
    2513                 :                                 char *prot_name;
    2514                 :                                 int prot_name_length;
    2515                 : 
    2516            5060 :                                 zend_mangle_property_name(&prot_name, &prot_name_length, "*", 1, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
    2517            5060 :                                 zend_hash_update(target_symbol_table, prot_name, prot_name_length+1, &property, sizeof(zval *), NULL);
    2518            5060 :                                 property_info.name = prot_name;
    2519            5060 :                                 property_info.name_length = prot_name_length;
    2520                 :                         }
    2521            5060 :                         break;
    2522                 :                 case ZEND_ACC_PUBLIC:
    2523            3740 :                         if (ce->parent) {
    2524                 :                                 char *prot_name;
    2525                 :                                 int prot_name_length;
    2526                 : 
    2527             880 :                                 zend_mangle_property_name(&prot_name, &prot_name_length, "*", 1, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
    2528             880 :                                 zend_hash_del(target_symbol_table, prot_name, prot_name_length+1);
    2529             880 :                                 pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS);
    2530                 :                         }
    2531            3740 :                         zend_hash_update(target_symbol_table, name, name_length+1, &property, sizeof(zval *), NULL);
    2532            3740 :                         property_info.name = ce->type & ZEND_INTERNAL_CLASS ? zend_strndup(name, name_length) : estrndup(name, name_length);
    2533            3740 :                         property_info.name_length = name_length;
    2534                 :                         break;
    2535                 :         }
    2536           14743 :         property_info.flags = access_type;
    2537           14743 :         property_info.h = zend_get_hash_value(property_info.name, property_info.name_length+1);
    2538                 : 
    2539           14743 :         property_info.doc_comment = doc_comment;
    2540           14743 :         property_info.doc_comment_len = doc_comment_len;
    2541                 : 
    2542           14743 :         property_info.ce = ce;
    2543                 : 
    2544           14743 :         zend_hash_update(&ce->properties_info, name, name_length + 1, &property_info, sizeof(zend_property_info), NULL);
    2545                 : 
    2546           14743 :         return SUCCESS;
    2547                 : }
    2548                 : 
    2549                 : ZEND_API int zend_declare_property_null(zend_class_entry *ce, char *name, int name_length, int access_type TSRMLS_DC)
    2550            4840 : {
    2551                 :         zval *property;
    2552                 : 
    2553            4840 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2554            4840 :                 property = malloc(sizeof(zval));
    2555                 :         } else {
    2556               0 :                 ALLOC_ZVAL(property);
    2557                 :         }
    2558            4840 :         INIT_ZVAL(*property);
    2559            4840 :         return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
    2560                 : }
    2561                 : 
    2562                 : ZEND_API int zend_declare_property_bool(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC)
    2563            1980 : {
    2564                 :         zval *property;
    2565                 : 
    2566            1980 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2567            1980 :                 property = malloc(sizeof(zval));
    2568                 :         } else {
    2569               0 :                 ALLOC_ZVAL(property);
    2570                 :         }
    2571            1980 :         INIT_PZVAL(property);
    2572            1980 :         ZVAL_BOOL(property, value);
    2573            1980 :         return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
    2574                 : }
    2575                 : 
    2576                 : ZEND_API int zend_declare_property_long(zend_class_entry *ce, char *name, int name_length, long value, int access_type TSRMLS_DC)
    2577            2200 : {
    2578                 :         zval *property;
    2579                 : 
    2580            2200 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2581            2200 :                 property = malloc(sizeof(zval));
    2582                 :         } else {
    2583               0 :                 ALLOC_ZVAL(property);
    2584                 :         }
    2585            2200 :         INIT_PZVAL(property);
    2586            2200 :         ZVAL_LONG(property, value);
    2587            2200 :         return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
    2588                 : }
    2589                 : 
    2590                 : ZEND_API int zend_declare_property_double(zend_class_entry *ce, char *name, int name_length, double value, int access_type TSRMLS_DC)
    2591             220 : {
    2592                 :         zval *property;
    2593                 : 
    2594             220 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2595             220 :                 property = malloc(sizeof(zval));
    2596                 :         } else {
    2597               0 :                 ALLOC_ZVAL(property);
    2598                 :         }
    2599             220 :         INIT_PZVAL(property);
    2600             220 :         ZVAL_DOUBLE(property, value);
    2601             220 :         return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
    2602                 : }
    2603                 : 
    2604                 : ZEND_API int zend_declare_property_string(zend_class_entry *ce, char *name, int name_length, char *value, int access_type TSRMLS_DC)
    2605            5500 : {
    2606                 :         zval *property;
    2607            5500 :         int len = strlen(value);
    2608                 : 
    2609            5500 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2610            5500 :                 property = malloc(sizeof(zval));
    2611            5500 :                 ZVAL_STRINGL(property, zend_strndup(value, len), len, 0);
    2612                 :         } else {
    2613               0 :                 ALLOC_ZVAL(property);
    2614               0 :                 ZVAL_STRINGL(property, value, len, 1);
    2615                 :         }
    2616            5500 :         INIT_PZVAL(property);
    2617            5500 :         return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
    2618                 : }
    2619                 : 
    2620                 : ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, char *name, int name_length, char *value, int value_len, int access_type TSRMLS_DC)
    2621               0 : {
    2622                 :         zval *property;
    2623                 : 
    2624               0 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2625               0 :                 property = malloc(sizeof(zval));
    2626               0 :                 ZVAL_STRINGL(property, zend_strndup(value, value_len), value_len, 0);
    2627                 :         } else {
    2628               0 :                 ALLOC_ZVAL(property);
    2629               0 :                 ZVAL_STRINGL(property, value, value_len, 1);
    2630                 :         }
    2631               0 :         INIT_PZVAL(property);
    2632               0 :         return zend_declare_property(ce, name, name_length, property, access_type TSRMLS_CC);
    2633                 : }
    2634                 : 
    2635                 : ZEND_API int zend_declare_class_constant(zend_class_entry *ce, char *name, size_t name_length, zval *value TSRMLS_DC)
    2636           28386 : {
    2637           28386 :         return zend_hash_update(&ce->constants_table, name, name_length+1, &value, sizeof(zval *), NULL);
    2638                 : }
    2639                 : 
    2640                 : ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, char *name, size_t name_length TSRMLS_DC)
    2641               0 : {
    2642                 :         zval *constant;
    2643                 : 
    2644               0 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2645               0 :                 constant = malloc(sizeof(zval));
    2646                 :         } else {
    2647               0 :                 ALLOC_ZVAL(constant);
    2648                 :         }
    2649               0 :         ZVAL_NULL(constant);
    2650               0 :         INIT_PZVAL(constant);
    2651               0 :         return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
    2652                 : }
    2653                 : 
    2654                 : ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, char *name, size_t name_length, long value TSRMLS_DC)
    2655           25966 : {
    2656                 :         zval *constant;
    2657                 : 
    2658           25966 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2659           25966 :                 constant = malloc(sizeof(zval));
    2660                 :         } else {
    2661               0 :                 ALLOC_ZVAL(constant);
    2662                 :         }
    2663           25966 :         ZVAL_LONG(constant, value);
    2664           25966 :         INIT_PZVAL(constant);
    2665           25966 :         return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
    2666                 : }
    2667                 : 
    2668                 : ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, char *name, size_t name_length, zend_bool value TSRMLS_DC)
    2669               0 : {
    2670                 :         zval *constant;
    2671                 : 
    2672               0 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2673               0 :                 constant = malloc(sizeof(zval));
    2674                 :         } else {
    2675               0 :                 ALLOC_ZVAL(constant);
    2676                 :         }
    2677               0 :         ZVAL_BOOL(constant, value);
    2678               0 :         INIT_PZVAL(constant);
    2679               0 :         return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
    2680                 : }
    2681                 : 
    2682                 : ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, char *name, size_t name_length, double value TSRMLS_DC)
    2683               0 : {
    2684                 :         zval *constant;
    2685                 : 
    2686               0 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2687               0 :                 constant = malloc(sizeof(zval));
    2688                 :         } else {
    2689               0 :                 ALLOC_ZVAL(constant);
    2690                 :         }
    2691               0 :         ZVAL_DOUBLE(constant, value);
    2692               0 :         INIT_PZVAL(constant);
    2693               0 :         return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
    2694                 : }
    2695                 : 
    2696                 : ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, char *name, size_t name_length, char *value, size_t value_length TSRMLS_DC)
    2697            2420 : {
    2698                 :         zval *constant;
    2699                 : 
    2700            2420 :         if (ce->type & ZEND_INTERNAL_CLASS) {
    2701            2420 :                 constant = malloc(sizeof(zval));
    2702            2420 :                 ZVAL_STRINGL(constant, zend_strndup(value, value_length), value_length, 0);
    2703                 :         } else {
    2704               0 :                 ALLOC_ZVAL(constant);
    2705               0 :                 ZVAL_STRINGL(constant, value, value_length, 1);
    2706                 :         }
    2707            2420 :         INIT_PZVAL(constant);
    2708            2420 :         return zend_declare_class_constant(ce, name, name_length, constant TSRMLS_CC);
    2709                 : }
    2710                 : 
    2711                 : ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, char *name, size_t name_length, char *value TSRMLS_DC)
    2712               0 : {
    2713               0 :         return zend_declare_class_constant_stringl(ce, name, name_length, value, strlen(value) TSRMLS_CC);
    2714                 : }
    2715                 : 
    2716                 : ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC)
    2717             705 : {
    2718                 :         zval *property;
    2719             705 :         zend_class_entry *old_scope = EG(scope);
    2720                 : 
    2721             705 :         EG(scope) = scope;
    2722                 : 
    2723             705 :         if (!Z_OBJ_HT_P(object)->write_property) {
    2724                 :                 char *class_name;
    2725                 :                 zend_uint class_name_len;
    2726                 : 
    2727               0 :                 zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC);
    2728                 : 
    2729               0 :                 zend_error(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, class_name);
    2730                 :         }
    2731             705 :         MAKE_STD_ZVAL(property);
    2732             705 :         ZVAL_STRINGL(property, name, name_length, 1);
    2733             705 :         Z_OBJ_HT_P(object)->write_property(object, property, value TSRMLS_CC);
    2734             705 :         zval_ptr_dtor(&property);
    2735                 : 
    2736             705 :         EG(scope) = old_scope;
    2737             705 : }
    2738                 : 
    2739                 : ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC)
    2740               0 : {
    2741                 :         zval *tmp;
    2742                 : 
    2743               0 :         ALLOC_ZVAL(tmp);
    2744               0 :         tmp->is_ref = 0;
    2745               0 :         tmp->refcount = 0;
    2746               0 :         ZVAL_NULL(tmp);
    2747               0 :         zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
    2748               0 : }
    2749                 : 
    2750                 : ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC)
    2751               1 : {
    2752                 :         zval *tmp;
    2753                 : 
    2754               1 :         ALLOC_ZVAL(tmp);
    2755               1 :         tmp->is_ref = 0;
    2756               1 :         tmp->refcount = 0;
    2757               1 :         ZVAL_BOOL(tmp, value);
    2758               1 :         zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
    2759               1 : }
    2760                 : 
    2761                 : ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC)
    2762             193 : {
    2763                 :         zval *tmp;
    2764                 : 
    2765             193 :         ALLOC_ZVAL(tmp);
    2766             193 :         tmp->is_ref = 0;
    2767             193 :         tmp->refcount = 0;
    2768             193 :         ZVAL_LONG(tmp, value);
    2769             193 :         zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
    2770             193 : }
    2771                 : 
    2772                 : ZEND_API void zend_update_property_double(zend_class_entry *scope, zval *object, char *name, int name_length, double value TSRMLS_DC)
    2773               0 : {
    2774                 :         zval *tmp;
    2775                 : 
    2776               0 :         ALLOC_ZVAL(tmp);
    2777               0 :         tmp->is_ref = 0;
    2778               0 :         tmp->refcount = 0;
    2779               0 :         ZVAL_DOUBLE(tmp, value);
    2780               0 :         zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
    2781               0 : }
    2782                 : 
    2783                 : ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, char *value TSRMLS_DC)
    2784             131 : {
    2785                 :         zval *tmp;
    2786                 : 
    2787             131 :         ALLOC_ZVAL(tmp);
    2788             131 :         tmp->is_ref = 0;
    2789             131 :         tmp->refcount = 0;
    2790             131 :         ZVAL_STRING(tmp, value, 1);
    2791             131 :         zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
    2792             131 : }
    2793                 : 
    2794                 : ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object, char *name, int name_length, char *value, int value_len TSRMLS_DC)
    2795              91 : {
    2796                 :         zval *tmp;
    2797                 : 
    2798              91 :         ALLOC_ZVAL(tmp);
    2799              91 :         tmp->is_ref = 0;
    2800              91 :         tmp->refcount = 0;
    2801              91 :         ZVAL_STRINGL(tmp, value, value_len, 1);
    2802              91 :         zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
    2803              91 : }
    2804                 : 
    2805                 : ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, int name_length, zval *value TSRMLS_DC)
    2806              29 : {
    2807                 :         zval **property;
    2808              29 :         zend_class_entry *old_scope = EG(scope);
    2809                 : 
    2810              29 :         EG(scope) = scope;
    2811              29 :         property = zend_std_get_static_property(scope, name, name_length, 0 TSRMLS_CC);
    2812              29 :         EG(scope) = old_scope;
    2813              29 :         if (!property) {
    2814               0 :                 return FAILURE;
    2815                 :         } else {
    2816              29 :                 if (*property != value) {
    2817              29 :                         if (PZVAL_IS_REF(*property)) {
    2818               0 :                                 zval_dtor(*property);
    2819               0 :                                 Z_TYPE_PP(property) = Z_TYPE_P(value);
    2820               0 :                                 (*property)->value = value->value;
    2821               0 :                                 if (value->refcount > 0) {
    2822               0 :                                         zval_copy_ctor(*property);
    2823                 :                                 }
    2824                 :                         } else {
    2825              29 :                                 zval *garbage = *property;
    2826                 : 
    2827              29 :                                 value->refcount++;
    2828              29 :                                 if (PZVAL_IS_REF(value)) {
    2829               0 :                                         SEPARATE_ZVAL(&value);
    2830                 :                                 }
    2831              29 :                                 *property = value;
    2832              29 :                                 zval_ptr_dtor(&garbage);
    2833                 :                         }
    2834                 :                 }
    2835              29 :                 return SUCCESS;
    2836                 :         }
    2837                 : }
    2838                 : 
    2839                 : ZEND_API int zend_update_static_property_null(zend_class_entry *scope, char *name, int name_length TSRMLS_DC)
    2840               0 : {
    2841                 :         zval *tmp;
    2842                 : 
    2843               0 :         ALLOC_ZVAL(tmp);
    2844               0 :         tmp->is_ref = 0;
    2845               0 :         tmp->refcount = 0;
    2846               0 :         ZVAL_NULL(tmp);
    2847               0 :         return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
    2848                 : }
    2849                 : 
    2850                 : ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC)
    2851               6 : {
    2852                 :         zval *tmp;
    2853                 : 
    2854               6 :         ALLOC_ZVAL(tmp);
    2855               6 :         tmp->is_ref = 0;
    2856               6 :         tmp->refcount = 0;
    2857               6 :         ZVAL_BOOL(tmp, value);
    2858               6 :         return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
    2859                 : }
    2860                 : 
    2861                 : ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char *name, int name_length, long value TSRMLS_DC)
    2862               8 : {
    2863                 :         zval *tmp;
    2864                 : 
    2865               8 :         ALLOC_ZVAL(tmp);
    2866               8 :         tmp->is_ref = 0;
    2867               8 :         tmp->refcount = 0;
    2868               8 :         ZVAL_LONG(tmp, value);
    2869               8 :         return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
    2870                 : }
    2871                 : 
    2872                 : ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char *name, int name_length, double value TSRMLS_DC)
    2873               0 : {
    2874                 :         zval *tmp;
    2875                 : 
    2876               0 :         ALLOC_ZVAL(tmp);
    2877               0 :         tmp->is_ref = 0;
    2878               0 :         tmp->refcount = 0;
    2879               0 :         ZVAL_DOUBLE(tmp, value);
    2880               0 :         return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
    2881                 : }
    2882                 : 
    2883                 : ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char *name, int name_length, char *value TSRMLS_DC)
    2884               4 : {
    2885                 :         zval *tmp;
    2886                 : 
    2887               4 :         ALLOC_ZVAL(tmp);
    2888               4 :         tmp->is_ref = 0;
    2889               4 :         tmp->refcount = 0;
    2890               4 :         ZVAL_STRING(tmp, value, 1);
    2891               4 :         return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
    2892                 : }
    2893                 : 
    2894                 : ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char *name, int name_length, char *value, int value_len TSRMLS_DC)
    2895               7 : {
    2896                 :         zval *tmp;
    2897                 : 
    2898               7 :         ALLOC_ZVAL(tmp);
    2899               7 :         tmp->is_ref = 0;
    2900               7 :         tmp->refcount = 0;
    2901               7 :         ZVAL_STRINGL(tmp, value, value_len, 1);
    2902               7 :         return zend_update_static_property(scope, name, name_length, tmp TSRMLS_CC);
    2903                 : }
    2904                 : 
    2905                 : ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char *name, int name_length, zend_bool silent TSRMLS_DC)
    2906             874 : {
    2907                 :         zval *property, *value;
    2908             874 :         zend_class_entry *old_scope = EG(scope);
    2909                 : 
    2910             874 :         EG(scope) = scope;
    2911                 : 
    2912             874 :         if (!Z_OBJ_HT_P(object)->read_property) {
    2913                 :                 char *class_name;
    2914                 :                 zend_uint class_name_len;
    2915                 : 
    2916               0 :                 zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC);
    2917               0 :                 zend_error(E_CORE_ERROR, "Property %s of class %s cannot be read", name, class_name);
    2918                 :         }
    2919                 : 
    2920             874 :         MAKE_STD_ZVAL(property);
    2921             874 :         ZVAL_STRINGL(property, name, name_length, 1);
    2922             874 :         value = Z_OBJ_HT_P(object)->read_property(object, property, silent?BP_VAR_IS:BP_VAR_R TSRMLS_CC);
    2923             874 :         zval_ptr_dtor(&property);
    2924                 : 
    2925             874 :         EG(scope) = old_scope;
    2926             874 :         return value;
    2927                 : }
    2928                 : 
    2929                 : ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, int name_length, zend_bool silent TSRMLS_DC)
    2930               0 : {
    2931                 :         zval **property;
    2932               0 :         zend_class_entry *old_scope = EG(scope);
    2933                 : 
    2934               0 :         EG(scope) = scope;
    2935               0 :         property = zend_std_get_static_property(scope, name, name_length, silent TSRMLS_CC);
    2936               0 :         EG(scope) = old_scope;
    2937                 : 
    2938               0 :         return property?*property:NULL;
    2939                 : }
    2940                 : 
    2941                 : /*
    2942                 :  * Local variables:
    2943                 :  * tab-width: 4
    2944                 :  * c-basic-offset: 4
    2945                 :  * indent-tabs-mode: t
    2946                 :  * End:
    2947                 :  */

Generated by: LTP GCOV extension version 1.5