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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_2/Zend - zend_operators.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 973
Code covered: 82.8 % Executed lines: 806
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 2.00 of the Zend license,     |
       8                 :    | that is bundled with this package in the file LICENSE, and is        | 
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.zend.com/license/2_00.txt.                                |
      11                 :    | If you did not receive a copy of the Zend license and are unable to  |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@zend.com so we can mail you a copy immediately.              |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16                 :    |          Zeev Suraski <zeev@zend.com>                                |
      17                 :    +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: zend_operators.c 276004 2009-02-17 15:15:36Z mattwil $ */
      21                 : 
      22                 : #include <ctype.h>
      23                 : 
      24                 : #include "zend.h"
      25                 : #include "zend_operators.h"
      26                 : #include "zend_variables.h"
      27                 : #include "zend_globals.h"
      28                 : #include "zend_list.h"
      29                 : #include "zend_API.h"
      30                 : #include "zend_multiply.h"
      31                 : #include "zend_strtod.h"
      32                 : #include "zend_exceptions.h"
      33                 : 
      34                 : #define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
      35                 : 
      36                 : #if ZEND_USE_TOLOWER_L
      37                 : #include <locale.h>
      38                 : static _locale_t current_locale = NULL;
      39                 : /* this is true global! may lead to strange effects on ZTS, but so is setlocale() */
      40                 : #define zend_tolower(c) _tolower_l(c, current_locale)
      41                 : #else
      42                 : #define zend_tolower(c) tolower(c)
      43                 : #endif
      44                 : 
      45                 : ZEND_API int zend_atoi(const char *str, int str_len)
      46          719172 : {
      47                 :         int retval;
      48                 : 
      49          719172 :         if (!str_len) {
      50           53834 :                 str_len = strlen(str);
      51                 :         }
      52          719172 :         retval = strtol(str, NULL, 0);
      53          719172 :         if (str_len>0) {
      54          678899 :                 switch (str[str_len-1]) {
      55                 :                         case 'g':
      56                 :                         case 'G':
      57               4 :                                 retval *= 1024;
      58                 :                                 /* break intentionally missing */
      59                 :                         case 'm':
      60                 :                         case 'M':
      61           40699 :                                 retval *= 1024;
      62                 :                                 /* break intentionally missing */
      63                 :                         case 'k':
      64                 :                         case 'K':
      65           54265 :                                 retval *= 1024;
      66                 :                                 break;
      67                 :                 }
      68                 :         }
      69          719172 :         return retval;
      70                 : }
      71                 : 
      72                 : 
      73                 : ZEND_API double zend_string_to_double(const char *number, zend_uint length)
      74               0 : {
      75               0 :         double divisor = 10.0;
      76               0 :         double result = 0.0;
      77                 :         double exponent;
      78               0 :         const char *end = number+length;
      79               0 :         const char *digit = number;
      80                 : 
      81               0 :         if (!length) {
      82               0 :                 return result;
      83                 :         }
      84                 : 
      85               0 :         while (digit < end) {
      86               0 :                 if ((*digit <= '9' && *digit >= '0')) {
      87               0 :                         result *= 10;
      88               0 :                         result += *digit - '0';
      89               0 :                 } else if (*digit == '.') {
      90               0 :                         digit++;
      91               0 :                         break;
      92               0 :                 } else if (toupper(*digit) == 'E') {
      93               0 :                         exponent = (double) atoi(digit+1);
      94               0 :                         result *= pow(10.0, exponent);
      95               0 :                         return result;
      96                 :                 } else {
      97               0 :                         return result;
      98                 :                 }
      99               0 :                 digit++;
     100                 :         }
     101                 : 
     102               0 :         while (digit < end) {
     103               0 :                 if ((*digit <= '9' && *digit >= '0')) {
     104               0 :                         result += (*digit - '0') / divisor;
     105               0 :                         divisor *= 10;
     106               0 :                 } else if (toupper(*digit) == 'E') {
     107               0 :                         exponent = (double) atoi(digit+1);
     108               0 :                         result *= pow(10.0, exponent);
     109               0 :                         return result;
     110                 :                 } else {
     111               0 :                         return result;
     112                 :                 }
     113               0 :                 digit++;
     114                 :         }
     115               0 :         return result;
     116                 : }
     117                 : 
     118                 : 
     119                 : ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC)
     120          205054 : {
     121          205054 :         switch (op->type) {
     122                 :                 case IS_STRING:
     123                 :                         {
     124                 :                                 char *strval;
     125                 : 
     126          101158 :                                 strval = op->value.str.val;
     127          101158 :                                 if ((op->type=is_numeric_string(strval, op->value.str.len, &op->value.lval, &op->value.dval, 1)) == 0) {
     128              48 :                                         op->value.lval = 0;
     129              48 :                                         op->type = IS_LONG;
     130                 :                                 }
     131          101158 :                                 STR_FREE(strval);
     132          101158 :                                 break;
     133                 :                         }
     134                 :                 case IS_BOOL:
     135              39 :                         op->type = IS_LONG;
     136              39 :                         break;
     137                 :                 case IS_RESOURCE:
     138               7 :                         zend_list_delete(op->value.lval);
     139               7 :                         op->type = IS_LONG;
     140               7 :                         break;
     141                 :                 case IS_OBJECT:
     142               6 :                         convert_to_long_base(op, 10);
     143               6 :                         break;
     144                 :                 case IS_NULL:
     145              47 :                         op->type = IS_LONG;
     146              47 :                         op->value.lval = 0;
     147                 :                         break;
     148                 :         }
     149          205054 : }
     150                 : 
     151                 : #define zendi_convert_scalar_to_number(op, holder, result)                      \
     152                 :         if (op==result) {                                                                                               \
     153                 :                 if (op->type != IS_LONG) {                                                                   \
     154                 :                         convert_scalar_to_number(op TSRMLS_CC);                                 \
     155                 :                 }                                                                                                                       \
     156                 :         } else {                                                                                                                \
     157                 :                 switch ((op)->type) {                                                                                \
     158                 :                         case IS_STRING:                                                                                 \
     159                 :                                 {                                                                                                       \
     160                 :                                         if (((holder).type=is_numeric_string((op)->value.str.val, (op)->value.str.len, &(holder).value.lval, &(holder).value.dval, 1)) == 0) {    \
     161                 :                                                 (holder).value.lval = 0;                                                \
     162                 :                                                 (holder).type = IS_LONG;                                                \
     163                 :                                         }                                                                                                               \
     164                 :                                         (op) = &(holder);                                                                           \
     165                 :                                         break;                                                                                                  \
     166                 :                                 }                                                                                                                       \
     167                 :                         case IS_BOOL:                                                                                                   \
     168                 :                         case IS_RESOURCE:                                                                                               \
     169                 :                                 (holder).value.lval = (op)->value.lval;                                              \
     170                 :                                 (holder).type = IS_LONG;                                                                        \
     171                 :                                 (op) = &(holder);                                                                                   \
     172                 :                                 break;                                                                                                          \
     173                 :                         case IS_NULL:                                                                                                   \
     174                 :                                 (holder).value.lval = 0;                                                                        \
     175                 :                                 (holder).type = IS_LONG;                                                                        \
     176                 :                                 (op) = &(holder);                                                                                   \
     177                 :                                 break;                                                                                                          \
     178                 :                         case IS_OBJECT:                                                                                                 \
     179                 :                                 (holder) = (*(op));                                                                                     \
     180                 :                                 zval_copy_ctor(&(holder));                                                                  \
     181                 :                                 convert_to_long_base(&(holder), 10);                                                \
     182                 :                                 if ((holder).type == IS_LONG) {                                                         \
     183                 :                                         (op) = &(holder);                                                                           \
     184                 :                                 }                                                                                                                       \
     185                 :                                 break;                                                                                                          \
     186                 :                 }                                                                                                                                       \
     187                 :         }
     188                 : 
     189                 : #ifdef _WIN64
     190                 : # define DVAL_TO_LVAL(d, l) \
     191                 :         if ((d) > LONG_MAX) { \
     192                 :                 (l) = (long)(unsigned long)(__int64) (d); \
     193                 :         } else { \
     194                 :                 (l) = (long) (d); \
     195                 :         }
     196                 : #else
     197                 : # define DVAL_TO_LVAL(d, l) \
     198                 :         if ((d) > LONG_MAX) { \
     199                 :                 (l) = (unsigned long) (d); \
     200                 :         } else { \
     201                 :                 (l) = (long) (d); \
     202                 :         }
     203                 : #endif
     204                 : 
     205                 : #define zendi_convert_to_long(op, holder, result)                                       \
     206                 :         if (op == result) {                                                                                             \
     207                 :                 convert_to_long(op);                                                                            \
     208                 :         } else if ((op)->type != IS_LONG) {                                                          \
     209                 :                 switch ((op)->type) {                                                                                \
     210                 :                         case IS_NULL:                                                                                   \
     211                 :                                 (holder).value.lval = 0;                                                        \
     212                 :                                 break;                                                                                          \
     213                 :                         case IS_DOUBLE:                                                                                 \
     214                 :                                 DVAL_TO_LVAL((op)->value.dval, (holder).value.lval); \
     215                 :                                 break;                                                                                          \
     216                 :                         case IS_STRING:                                                                                 \
     217                 :                                 (holder).value.lval = strtol((op)->value.str.val, NULL, 10);                                 \
     218                 :                                 break;                                                                                          \
     219                 :                         case IS_ARRAY:                                                                                  \
     220                 :                                 (holder).value.lval = (zend_hash_num_elements((op)->value.ht)?1:0);                          \
     221                 :                                 break;                                                                                          \
     222                 :                         case IS_OBJECT:                                                                                 \
     223                 :                                 (holder) = (*(op));                                                                     \
     224                 :                                 zval_copy_ctor(&(holder));                                                  \
     225                 :                                 convert_to_long_base(&(holder), 10);                                \
     226                 :                                 break;                                                                                          \
     227                 :                         case IS_BOOL:                                                                                   \
     228                 :                         case IS_RESOURCE:                                                                               \
     229                 :                                 (holder).value.lval = (op)->value.lval;                              \
     230                 :                                 break;                                                                                          \
     231                 :                         default:                                                                                                \
     232                 :                                 zend_error(E_WARNING, "Cannot convert to ordinal value");                                             \
     233                 :                                 (holder).value.lval = 0;                                                        \
     234                 :                                 break;                                                                                          \
     235                 :                 }                                                                                                                       \
     236                 :                 (holder).type = IS_LONG;                                                                        \
     237                 :                 (op) = &(holder);                                                                                   \
     238                 :         }
     239                 : 
     240                 : 
     241                 : #define zendi_convert_to_boolean(op, holder, result)                            \
     242                 :         if (op==result) {                                                                                               \
     243                 :                 convert_to_boolean(op);                                                                         \
     244                 :         } else if ((op)->type != IS_BOOL) {                                                          \
     245                 :                 switch ((op)->type) {                                                                                \
     246                 :                         case IS_NULL:                                                                                   \
     247                 :                                 (holder).value.lval = 0;                                                        \
     248                 :                                 break;                                                                                          \
     249                 :                         case IS_RESOURCE:                                                                               \
     250                 :                         case IS_LONG:                                                                                   \
     251                 :                                 (holder).value.lval = ((op)->value.lval ? 1 : 0);    \
     252                 :                                 break;                                                                                          \
     253                 :                         case IS_DOUBLE:                                                                                 \
     254                 :                                 (holder).value.lval = ((op)->value.dval ? 1 : 0);    \
     255                 :                                 break;                                                                                          \
     256                 :                         case IS_STRING:                                                                                 \
     257                 :                                 if ((op)->value.str.len == 0                                         \
     258                 :                                         || ((op)->value.str.len==1 && (op)->value.str.val[0]=='0')) {     \
     259                 :                                         (holder).value.lval = 0;                                                \
     260                 :                                 } else {                                                                                        \
     261                 :                                         (holder).value.lval = 1;                                                \
     262                 :                                 }                                                                                                       \
     263                 :                                 break;                                                                                          \
     264                 :                         case IS_ARRAY:                                                                                  \
     265                 :                                 (holder).value.lval = (zend_hash_num_elements((op)->value.ht)?1:0);  \
     266                 :                                 break;                                                                                          \
     267                 :                         case IS_OBJECT:                                                                                 \
     268                 :                                 (holder) = (*(op));                                                                     \
     269                 :                                 zval_copy_ctor(&(holder));                                                  \
     270                 :                                 convert_to_boolean(&(holder));                                              \
     271                 :                                 break;                                                                                          \
     272                 :                         default:                                                                                                \
     273                 :                                 (holder).value.lval = 0;                                                        \
     274                 :                                 break;                                                                                          \
     275                 :                 }                                                                                                                       \
     276                 :                 (holder).type = IS_BOOL;                                                                        \
     277                 :                 (op) = &(holder);                                                                                   \
     278                 :         }
     279                 : 
     280                 : 
     281                 : #define convert_object_to_type(op, ctype, conv_func)                                                                            \
     282                 :         if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                           \
     283                 :                 zval dst;                                                                                                                                                       \
     284                 :                 if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) {                 \
     285                 :                         zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
     286                 :                         "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name,                    \
     287                 :                         zend_get_type_by_const(ctype));                                                                                                 \
     288                 :                 } else {                                                                                                                                                        \
     289                 :                         zval_dtor(op);                                                                                                                                  \
     290                 :                         Z_TYPE_P(op) = ctype;                                                                                                                   \
     291                 :                         op->value = dst.value;                                                                                                                       \
     292                 :                 }                                                                                                                                                                       \
     293                 :         } else {                                                                                                                                                                \
     294                 :                 if(Z_OBJ_HT_P(op)->get) {                                                                                                                    \
     295                 :                         zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);                                                             \
     296                 :                         if(Z_TYPE_P(newop) != IS_OBJECT) {                                                                                              \
     297                 :                                 /* for safety - avoid loop */                                                                                           \
     298                 :                                 zval_dtor(op);                                                                                                                          \
     299                 :                                 *op = *newop;                                                                                                                           \
     300                 :                                 FREE_ZVAL(newop);                                                                                                                       \
     301                 :                                 conv_func(op);                                                                                                                          \
     302                 :                         }                                                                                                                                                               \
     303                 :                 }                                                                                                                                                                       \
     304                 :         }
     305                 : 
     306                 : ZEND_API void convert_to_long(zval *op)
     307          701723 : {
     308          701723 :         if ((op)->type != IS_LONG) {
     309           19889 :                 convert_to_long_base(op, 10);
     310                 :         }
     311          701723 : }
     312                 : 
     313                 : ZEND_API void convert_to_long_base(zval *op, int base)
     314           23717 : {
     315                 :         char *strval;
     316                 :         long tmp;
     317                 : 
     318           23717 :         switch (op->type) {
     319                 :                 case IS_NULL:
     320            1211 :                         op->value.lval = 0;
     321            1211 :                         break;
     322                 :                 case IS_RESOURCE: {
     323                 :                                 TSRMLS_FETCH();
     324                 : 
     325             145 :                                 zend_list_delete(op->value.lval);
     326                 :                         }
     327                 :                         /* break missing intentionally */
     328                 :                 case IS_BOOL:
     329                 :                 case IS_LONG:
     330            8775 :                         break;
     331                 :                 case IS_DOUBLE:
     332            8714 :                         DVAL_TO_LVAL(op->value.dval, op->value.lval);
     333            8714 :                         break;
     334                 :                 case IS_STRING:
     335            3896 :                         strval = op->value.str.val;
     336            3896 :                         op->value.lval = strtol(strval, NULL, base);
     337            3896 :                         STR_FREE(strval);
     338            3896 :                         break;
     339                 :                 case IS_ARRAY:
     340            1020 :                         tmp = (zend_hash_num_elements(op->value.ht)?1:0);
     341            1020 :                         zval_dtor(op);
     342            1020 :                         op->value.lval = tmp;
     343            1020 :                         break;
     344                 :                 case IS_OBJECT:
     345                 :                         {
     346             101 :                                 int retval = 1;
     347                 :                                 TSRMLS_FETCH();
     348                 : 
     349             101 :                                 convert_object_to_type(op, IS_LONG, convert_to_long);
     350                 : 
     351             101 :                                 if (op->type == IS_LONG) {
     352             101 :                                         return;
     353                 :                                 }
     354                 : 
     355               0 :                                 if (EG(ze1_compatibility_mode)) {
     356               0 :                                         HashTable *ht = Z_OBJPROP_P(op);
     357               0 :                                         if (ht) {
     358               0 :                                                 retval = (zend_hash_num_elements(ht)?1:0);
     359                 :                                         }
     360                 :                                 } else {
     361               0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
     362                 :                                 }
     363               0 :                                 zval_dtor(op);
     364               0 :                                 ZVAL_LONG(op, retval);
     365               0 :                                 return;
     366                 :                         }
     367                 :                 default:
     368               0 :                         zend_error(E_WARNING, "Cannot convert to ordinal value");
     369               0 :                         zval_dtor(op);
     370               0 :                         op->value.lval = 0;
     371                 :                         break;
     372                 :         }
     373                 : 
     374           23616 :         op->type = IS_LONG;
     375                 : }
     376                 : 
     377                 : 
     378                 : ZEND_API void convert_to_double(zval *op)
     379          330582 : {
     380                 :         char *strval;
     381                 :         double tmp;
     382                 : 
     383          330582 :         switch (op->type) {
     384                 :                 case IS_NULL:
     385             335 :                         op->value.dval = 0.0;
     386             335 :                         break;
     387                 :                 case IS_RESOURCE: {
     388                 :                                 TSRMLS_FETCH();
     389                 : 
     390              57 :                                 zend_list_delete(op->value.lval);
     391                 :                         }
     392                 :                         /* break missing intentionally */
     393                 :                 case IS_BOOL:
     394                 :                 case IS_LONG:
     395          256420 :                         op->value.dval = (double) op->value.lval;
     396          256420 :                         break;
     397                 :                 case IS_DOUBLE:
     398           72368 :                         break;
     399                 :                 case IS_STRING:
     400            1050 :                         strval = op->value.str.val;
     401                 : 
     402            1050 :                         op->value.dval = zend_strtod(strval, NULL);
     403            1050 :                         STR_FREE(strval);
     404            1050 :                         break;
     405                 :                 case IS_ARRAY:
     406             380 :                         tmp = (zend_hash_num_elements(op->value.ht)?1:0);
     407             380 :                         zval_dtor(op);
     408             380 :                         op->value.dval = tmp;
     409             380 :                         break;
     410                 :                 case IS_OBJECT:
     411                 :                         {
     412              29 :                                 double retval = 1.0;
     413                 :                                 TSRMLS_FETCH();
     414                 :                                 
     415              29 :                                 convert_object_to_type(op, IS_DOUBLE, convert_to_double);
     416                 : 
     417              29 :                                 if (op->type == IS_DOUBLE) {
     418              29 :                                         return;
     419                 :                                 }
     420                 : 
     421               0 :                                 if (EG(ze1_compatibility_mode)) {
     422               0 :                                         HashTable *ht = Z_OBJPROP_P(op);
     423               0 :                                         if (ht) {
     424               0 :                                                 retval = (zend_hash_num_elements(ht)?1.0:0.0);
     425                 :                                         }
     426                 :                                 } else {
     427               0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
     428                 :                                 }
     429                 : 
     430               0 :                                 zval_dtor(op);
     431               0 :                                 ZVAL_DOUBLE(op, retval);
     432               0 :                                 break;
     433                 :                         }       
     434                 :                 default:
     435               0 :                         zend_error(E_WARNING, "Cannot convert to real value (type=%d)", op->type);
     436               0 :                         zval_dtor(op);
     437               0 :                         op->value.dval = 0;
     438                 :                         break;
     439                 :         }
     440          330553 :         op->type = IS_DOUBLE;
     441                 : }
     442                 : 
     443                 : 
     444                 : ZEND_API void convert_to_null(zval *op)
     445            1093 : {
     446            1093 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     447               6 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     448                 :                         zval *org;
     449                 :                         TSRMLS_FETCH();
     450                 : 
     451               6 :                         ALLOC_ZVAL(org);
     452               6 :                         *org = *op;
     453               6 :                         if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
     454               0 :                                 zval_dtor(org);
     455               0 :                                 return;
     456                 :                         }
     457               6 :                         *op = *org;
     458               6 :                         FREE_ZVAL(org);
     459                 :                 }
     460                 :         }
     461                 : 
     462            1093 :         zval_dtor(op);
     463            1093 :         Z_TYPE_P(op) = IS_NULL;
     464                 : }
     465                 : 
     466                 : 
     467                 : ZEND_API void convert_to_boolean(zval *op)
     468         1735618 : {
     469                 :         char *strval;
     470                 :         int tmp;
     471                 : 
     472         1735618 :         switch (op->type) {
     473                 :                 case IS_BOOL:
     474            3423 :                         break;
     475                 :                 case IS_NULL:
     476             107 :                         op->value.lval = 0;
     477             107 :                         break;
     478                 :                 case IS_RESOURCE: {
     479                 :                                 TSRMLS_FETCH();
     480                 : 
     481              11 :                                 zend_list_delete(op->value.lval);
     482                 :                         }
     483                 :                         /* break missing intentionally */
     484                 :                 case IS_LONG:
     485         1660821 :                         op->value.lval = (op->value.lval ? 1 : 0);
     486         1660821 :                         break;
     487                 :                 case IS_DOUBLE:
     488             167 :                         op->value.lval = (op->value.dval ? 1 : 0);
     489             167 :                         break;
     490                 :                 case IS_STRING:
     491             248 :                         strval = op->value.str.val;
     492                 : 
     493             310 :                         if (op->value.str.len == 0
     494                 :                                 || (op->value.str.len==1 && op->value.str.val[0]=='0')) {
     495              62 :                                 op->value.lval = 0;
     496                 :                         } else {
     497             186 :                                 op->value.lval = 1;
     498                 :                         }
     499             248 :                         STR_FREE(strval);
     500             248 :                         break;
     501                 :                 case IS_ARRAY:
     502              30 :                         tmp = (zend_hash_num_elements(op->value.ht)?1:0);
     503              30 :                         zval_dtor(op);
     504              30 :                         op->value.lval = tmp;
     505              30 :                         break;
     506                 :                 case IS_OBJECT:
     507                 :                         {
     508           70822 :                                 zend_bool retval = 1;
     509                 :                                 TSRMLS_FETCH();
     510                 : 
     511           70822 :                                 convert_object_to_type(op, IS_BOOL, convert_to_boolean);
     512                 : 
     513           70822 :                                 if (op->type == IS_BOOL) {
     514           70822 :                                         return;
     515                 :                                 }
     516                 :                                         
     517               0 :                                 if (EG(ze1_compatibility_mode)) {
     518               0 :                                         HashTable *ht = Z_OBJPROP_P(op);
     519               0 :                                         if (ht) {
     520               0 :                                                 retval = (zend_hash_num_elements(ht)?1:0);
     521                 :                                         }
     522                 :                                 }
     523                 :                                 
     524               0 :                                 zval_dtor(op);
     525               0 :                                 ZVAL_BOOL(op, retval);
     526               0 :                                 break;
     527                 :                         }
     528                 :                 default:
     529               0 :                         zval_dtor(op);
     530               0 :                         op->value.lval = 0;
     531                 :                         break;
     532                 :         }
     533         1664796 :         op->type = IS_BOOL;
     534                 : }
     535                 : 
     536                 : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC)
     537         2017847 : {
     538                 :         long lval;
     539                 :         double dval;
     540                 : 
     541         2017847 :         switch (op->type) {
     542                 :                 case IS_NULL:
     543            2676 :                         op->value.str.val = STR_EMPTY_ALLOC();
     544            2676 :                         op->value.str.len = 0;
     545            2676 :                         break;
     546                 :                 case IS_STRING:
     547               0 :                         break;
     548                 :                 case IS_BOOL:
     549            9242 :                         if (op->value.lval) {
     550             873 :                                 op->value.str.val = estrndup_rel("1", 1);
     551             873 :                                 op->value.str.len = 1;
     552                 :                         } else {
     553            8369 :                                 op->value.str.val = STR_EMPTY_ALLOC();
     554            8369 :                                 op->value.str.len = 0;
     555                 :                         }
     556            9242 :                         break;
     557                 :                 case IS_RESOURCE: {
     558             163 :                         long tmp = op->value.lval;
     559                 :                         TSRMLS_FETCH();
     560                 : 
     561             163 :                         zend_list_delete(op->value.lval);
     562             163 :                         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "Resource id #%ld", tmp);
     563             163 :                         break;
     564                 :                 }
     565                 :                 case IS_LONG:
     566         2002639 :                         lval = op->value.lval;
     567                 : 
     568         2002639 :                         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%ld", lval);  /* SAFE */
     569         2002639 :                         break;
     570                 :                 case IS_DOUBLE: {
     571                 :                         TSRMLS_FETCH();
     572            2148 :                         dval = op->value.dval;
     573            2148 :                         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%.*G", (int) EG(precision), dval);  /* SAFE */
     574                 :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     575            2148 :                         break;
     576                 :                 }
     577                 :                 case IS_ARRAY:
     578             690 :                         zend_error(E_NOTICE, "Array to string conversion");
     579             690 :                         zval_dtor(op);
     580             690 :                         op->value.str.val = estrndup_rel("Array", sizeof("Array")-1);
     581             690 :                         op->value.str.len = sizeof("Array")-1;
     582             690 :                         break;
     583                 :                 case IS_OBJECT: {
     584                 :                         TSRMLS_FETCH();
     585                 :                         
     586             289 :                         convert_object_to_type(op, IS_STRING, convert_to_string);
     587                 : 
     588             278 :                         if (op->type == IS_STRING) {
     589             235 :                                 return;
     590                 :                         }
     591                 : 
     592              43 :                         zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
     593              43 :                         zval_dtor(op);
     594              43 :                         op->value.str.val = estrndup_rel("Object", sizeof("Object")-1);
     595              43 :                         op->value.str.len = sizeof("Object")-1;
     596              43 :                         break;
     597                 :                 }
     598                 :                 default:
     599               0 :                         zval_dtor(op);
     600               0 :                         ZVAL_BOOL(op, 0);
     601                 :                         break;
     602                 :         }
     603         2017601 :         op->type = IS_STRING;
     604                 : }
     605                 : 
     606                 : 
     607                 : static void convert_scalar_to_array(zval *op, int type)
     608             336 : {
     609                 :         zval *entry;
     610                 :         
     611             336 :         ALLOC_ZVAL(entry);
     612             336 :         *entry = *op;
     613             336 :         INIT_PZVAL(entry);
     614                 :         
     615             336 :         switch (type) {
     616                 :                 case IS_ARRAY:
     617             222 :                         ALLOC_HASHTABLE(op->value.ht);
     618             222 :                         zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     619             222 :                         zend_hash_index_update(op->value.ht, 0, (void *) &entry, sizeof(zval *), NULL);
     620             222 :                         op->type = IS_ARRAY;
     621             222 :                         break;
     622                 :                 case IS_OBJECT:
     623                 :                         {
     624                 :                                 /* OBJECTS_OPTIMIZE */
     625                 :                                 TSRMLS_FETCH();
     626                 : 
     627             114 :                                 object_init(op);
     628             114 :                                 zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
     629                 :                         }
     630                 :                         break;
     631                 :         }
     632             336 : }
     633                 : 
     634                 : 
     635                 : ZEND_API void convert_to_array(zval *op)
     636           13775 : {
     637                 :         TSRMLS_FETCH();
     638                 : 
     639           13775 :         switch (op->type) {
     640                 :                 case IS_ARRAY:
     641           13509 :                         return;
     642                 :                         break;
     643                 : /* OBJECTS_OPTIMIZE */
     644                 :                 case IS_OBJECT:
     645                 :                         {
     646                 :                                 zval *tmp;
     647                 :                                 HashTable *ht;
     648                 : 
     649              15 :                                 ALLOC_HASHTABLE(ht);
     650              15 :                                 zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     651              15 :                                 if (Z_OBJ_HT_P(op)->get_properties) {
     652              15 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
     653              15 :                                         if(obj_ht) {
     654              15 :                                                 zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     655                 :                                         }
     656                 :                                 } else {
     657               0 :                                         convert_object_to_type(op, IS_ARRAY, convert_to_array);
     658                 : 
     659               0 :                                         if (op->type == IS_ARRAY) {
     660               0 :                                                 zend_hash_destroy(ht);
     661               0 :                                                 FREE_HASHTABLE(ht);
     662               0 :                                                 return;
     663                 :                                         }
     664                 :                                 }
     665              15 :                                 zval_dtor(op);
     666              15 :                                 op->type = IS_ARRAY;
     667              15 :                                 op->value.ht = ht;
     668                 :                         }
     669              15 :                         return;
     670                 :                 case IS_NULL:
     671              29 :                         ALLOC_HASHTABLE(op->value.ht);
     672              29 :                         zend_hash_init(op->value.ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     673              29 :                         op->type = IS_ARRAY;
     674              29 :                         break;
     675                 :                 default:
     676             222 :                         convert_scalar_to_array(op, IS_ARRAY);
     677                 :                         break;
     678                 :         }
     679                 : }
     680                 : 
     681                 : 
     682                 : ZEND_API void convert_to_object(zval *op)
     683             198 : {
     684             198 :         switch (op->type) {
     685                 :                 case IS_ARRAY:
     686                 :                         {
     687                 :                                 /* OBJECTS_OPTIMIZE */
     688                 :                                 TSRMLS_FETCH();
     689                 : 
     690              67 :                                 object_and_properties_init(op, zend_standard_class_def, op->value.ht);
     691              67 :                                 return;
     692                 :                                 break;
     693                 :                         }
     694                 :                 case IS_OBJECT:
     695              10 :                         return;
     696                 :                 case IS_NULL:
     697                 :                         {
     698                 :                                 /* OBJECTS_OPTIMIZE */
     699                 :                                 TSRMLS_FETCH();
     700                 : 
     701               7 :                                 object_init(op);
     702               7 :                                 break;
     703                 :                         }
     704                 :                 default:
     705             114 :                         convert_scalar_to_array(op, IS_OBJECT);
     706                 :                         break;
     707                 :         }
     708                 : }
     709                 : 
     710                 : ZEND_API void multi_convert_to_long_ex(int argc, ...)
     711               3 : {
     712                 :         zval **arg;
     713                 :         va_list ap;
     714                 :         
     715               3 :         va_start(ap, argc);
     716                 : 
     717              18 :         while (argc--) {
     718              12 :                 arg = va_arg(ap, zval **);
     719              12 :                 convert_to_long_ex(arg);
     720                 :         }
     721                 :         
     722               3 :         va_end(ap);
     723               3 : }
     724                 : 
     725                 : ZEND_API void multi_convert_to_double_ex(int argc, ...)
     726               0 : {
     727                 :         zval **arg;
     728                 :         va_list ap;
     729                 :         
     730               0 :         va_start(ap, argc);
     731                 : 
     732               0 :         while (argc--) {        
     733               0 :                 arg = va_arg(ap, zval **);
     734               0 :                 convert_to_double_ex(arg);
     735                 :         }
     736                 :         
     737               0 :         va_end(ap);
     738               0 : }
     739                 : 
     740                 : ZEND_API void multi_convert_to_string_ex(int argc, ...)
     741               0 : {
     742                 :         zval **arg;
     743                 :         va_list ap;
     744                 :         
     745               0 :         va_start(ap, argc);
     746                 : 
     747               0 :         while (argc--) {        
     748               0 :                 arg = va_arg(ap, zval **);
     749               0 :                 convert_to_string_ex(arg);
     750                 :         }
     751                 :         
     752               0 :         va_end(ap);
     753               0 : }
     754                 : 
     755                 : ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     756          220531 : {
     757                 :         zval op1_copy, op2_copy;
     758                 : 
     759          220531 :         if (op1->type == IS_ARRAY && op2->type == IS_ARRAY) {
     760                 :                 zval *tmp;
     761                 : 
     762               5 :                 if ((result == op1) && (result == op2)) {
     763                 :                         /* $a += $a */
     764               1 :                         return SUCCESS;
     765                 :                 }
     766               4 :                 if (result != op1) {
     767               3 :                         *result = *op1;
     768               3 :                         zval_copy_ctor(result);
     769                 :                 }
     770               4 :                 zend_hash_merge(result->value.ht, op2->value.ht, (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
     771               4 :                 return SUCCESS;
     772                 :         }
     773          220526 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     774          220526 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     775                 : 
     776                 : 
     777          220526 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     778          218950 :                 long lval = op1->value.lval + op2->value.lval;
     779                 :                 
     780                 :                 /* check for overflow by comparing sign bits */
     781          218970 :                 if ( (op1->value.lval & LONG_SIGN_MASK) == (op2->value.lval & LONG_SIGN_MASK) 
     782                 :                         && (op1->value.lval & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     783                 : 
     784              20 :                         result->value.dval = (double) op1->value.lval + (double) op2->value.lval;
     785              20 :                         result->type = IS_DOUBLE;
     786                 :                 } else {
     787          218930 :                         result->value.lval = lval;
     788          218930 :                         result->type = IS_LONG;
     789                 :                 }
     790          218950 :                 return SUCCESS;
     791                 :         }
     792            1576 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     793                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     794            1356 :                 result->value.dval = (op1->type == IS_LONG ?
     795                 :                                                  (((double) op1->value.lval) + op2->value.dval) :
     796                 :                                                  (op1->value.dval + ((double) op2->value.lval)));
     797            1356 :                 result->type = IS_DOUBLE;
     798            1356 :                 return SUCCESS;
     799                 :         }
     800             220 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     801             216 :                 result->type = IS_DOUBLE;
     802             216 :                 result->value.dval = op1->value.dval + op2->value.dval;
     803             216 :                 return SUCCESS;
     804                 :         }
     805               4 :         zend_error(E_ERROR, "Unsupported operand types");
     806               0 :         return FAILURE;                         /* unknown datatype */
     807                 : }
     808                 : 
     809                 : 
     810                 : ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     811          197669 : {
     812                 :         zval op1_copy, op2_copy;
     813                 :         
     814          197669 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     815          197669 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     816                 : 
     817          197669 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     818          195383 :                 long lval = op1->value.lval - op2->value.lval;
     819                 :                 
     820                 :                 /* check for overflow by comparing sign bits */
     821          195400 :                 if ( (op1->value.lval & LONG_SIGN_MASK) != (op2->value.lval & LONG_SIGN_MASK) 
     822                 :                         && (op1->value.lval & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     823                 : 
     824              17 :                         result->value.dval = (double) op1->value.lval - (double) op2->value.lval;
     825              17 :                         result->type = IS_DOUBLE;
     826                 :                 } else {
     827          195366 :                         result->value.lval = lval;
     828          195366 :                         result->type = IS_LONG;
     829                 :                 }
     830          195383 :                 return SUCCESS;
     831                 :         }
     832            2286 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     833                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     834            2080 :                 result->value.dval = (op1->type == IS_LONG ?
     835                 :                                                  (((double) op1->value.lval) - op2->value.dval) :
     836                 :                                                  (op1->value.dval - ((double) op2->value.lval)));
     837            2080 :                 result->type = IS_DOUBLE;
     838            2080 :                 return SUCCESS;
     839                 :         }
     840             206 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     841             205 :                 result->type = IS_DOUBLE;
     842             205 :                 result->value.dval = op1->value.dval - op2->value.dval;
     843             205 :                 return SUCCESS;
     844                 :         }
     845               1 :         zend_error(E_ERROR, "Unsupported operand types");
     846               0 :         return FAILURE;                         /* unknown datatype */
     847                 : }
     848                 : 
     849                 : 
     850                 : ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     851            5018 : {
     852                 :         zval op1_copy, op2_copy;
     853                 :         
     854            5018 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     855            5018 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     856                 : 
     857            5018 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     858                 :                 long overflow;
     859                 : 
     860            4687 :                 ZEND_SIGNED_MULTIPLY_LONG(op1->value.lval,op2->value.lval, result->value.lval,result->value.dval,overflow);
     861            4687 :                 result->type = overflow ? IS_DOUBLE : IS_LONG;       
     862            4687 :                 return SUCCESS;
     863                 :         }
     864             331 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     865                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     866             121 :                 result->value.dval = (op1->type == IS_LONG ?
     867                 :                                                  (((double) op1->value.lval) * op2->value.dval) :
     868                 :                                                  (op1->value.dval * ((double) op2->value.lval)));
     869             121 :                 result->type = IS_DOUBLE;
     870             121 :                 return SUCCESS;
     871                 :         }
     872             210 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     873             209 :                 result->type = IS_DOUBLE;
     874             209 :                 result->value.dval = op1->value.dval * op2->value.dval;
     875             209 :                 return SUCCESS;
     876                 :         }
     877               1 :         zend_error(E_ERROR, "Unsupported operand types");
     878               0 :         return FAILURE;                         /* unknown datatype */
     879                 : }
     880                 : 
     881                 : ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     882           67726 : {
     883                 :         zval op1_copy, op2_copy;
     884                 :         
     885           67726 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
     886           67726 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
     887                 : 
     888           67726 :         if ((op2->type == IS_LONG && op2->value.lval == 0) || (op2->type == IS_DOUBLE && op2->value.dval == 0.0)) {
     889              45 :                 zend_error(E_WARNING, "Division by zero");
     890              45 :                 ZVAL_BOOL(result, 0);
     891              45 :                 return FAILURE;                 /* division by zero */
     892                 :         }
     893           67681 :         if (op1->type == IS_LONG && op2->type == IS_LONG) {
     894           63705 :                 if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
     895                 :                         /* Prevent overflow error/crash */
     896               0 :                         ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
     897               0 :                         return SUCCESS;
     898                 :                 }
     899           63705 :                 if (op1->value.lval % op2->value.lval == 0) { /* integer */
     900           51429 :                         result->type = IS_LONG;
     901           51429 :                         result->value.lval = op1->value.lval / op2->value.lval;
     902                 :                 } else {
     903           12276 :                         result->type = IS_DOUBLE;
     904           12276 :                         result->value.dval = ((double) op1->value.lval) / op2->value.lval;
     905                 :                 }
     906           63705 :                 return SUCCESS;
     907                 :         }
     908            3976 :         if ((op1->type == IS_DOUBLE && op2->type == IS_LONG)
     909                 :                 || (op1->type == IS_LONG && op2->type == IS_DOUBLE)) {
     910            3915 :                 result->value.dval = (op1->type == IS_LONG ?
     911                 :                                                  (((double) op1->value.lval) / op2->value.dval) :
     912                 :                                                  (op1->value.dval / ((double) op2->value.lval)));
     913            3915 :                 result->type = IS_DOUBLE;
     914            3915 :                 return SUCCESS;
     915                 :         }
     916              61 :         if (op1->type == IS_DOUBLE && op2->type == IS_DOUBLE) {
     917              60 :                 result->type = IS_DOUBLE;
     918              60 :                 result->value.dval = op1->value.dval / op2->value.dval;
     919              60 :                 return SUCCESS;
     920                 :         }
     921               1 :         zend_error(E_ERROR, "Unsupported operand types");
     922               0 :         return FAILURE;                         /* unknown datatype */
     923                 : }
     924                 : 
     925                 : 
     926                 : ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     927           40975 : {
     928                 :         zval op1_copy, op2_copy;
     929                 :         
     930           40975 :         zendi_convert_to_long(op1, op1_copy, result);
     931           40975 :         zendi_convert_to_long(op2, op2_copy, result);
     932                 : 
     933           40975 :         if (op2->value.lval == 0) {
     934              43 :                 zend_error(E_WARNING, "Division by zero");
     935              43 :                 ZVAL_BOOL(result, 0);
     936              43 :                 return FAILURE;                 /* modulus by zero */
     937                 :         }
     938                 : 
     939           40932 :         if (op2->value.lval == -1) {
     940                 :                 /* Prevent overflow error/crash if op1==LONG_MIN */
     941               3 :                 ZVAL_LONG(result, 0);
     942               3 :                 return SUCCESS;
     943                 :         }
     944                 : 
     945           40929 :         result->type = IS_LONG;
     946           40929 :         result->value.lval = op1->value.lval % op2->value.lval;
     947           40929 :         return SUCCESS;
     948                 : }
     949                 : 
     950                 : 
     951                 : 
     952                 : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     953               0 : {
     954                 :         zval op1_copy, op2_copy;
     955                 :         
     956               0 :         result->type = IS_BOOL;
     957                 : 
     958               0 :         zendi_convert_to_boolean(op1, op1_copy, result);
     959               0 :         zendi_convert_to_boolean(op2, op2_copy, result);
     960               0 :         result->value.lval = op1->value.lval ^ op2->value.lval;
     961               0 :         return SUCCESS;
     962                 : }
     963                 : 
     964                 : 
     965                 : ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC)
     966         2726777 : {
     967                 :         zval op1_copy;
     968                 :         
     969         2726777 :         zendi_convert_to_boolean(op1, op1_copy, result);
     970                 : 
     971         2726777 :         result->type = IS_BOOL;
     972         2726777 :         result->value.lval = !op1->value.lval;
     973         2726777 :         return SUCCESS;
     974                 : }
     975                 : 
     976                 : 
     977                 : ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC)
     978              95 : {
     979              95 :         zval op1_copy = *op1;
     980                 :         
     981              95 :         op1 = &op1_copy;
     982                 :         
     983              95 :         if (op1->type == IS_DOUBLE) {
     984               1 :                 op1->value.lval = (long) op1->value.dval;
     985               1 :                 op1->type = IS_LONG;
     986                 :         }
     987              95 :         if (op1->type == IS_LONG) {
     988              79 :                 result->value.lval = ~op1->value.lval;
     989              79 :                 result->type = IS_LONG;
     990              79 :                 return SUCCESS;
     991                 :         }
     992              16 :         if (op1->type == IS_STRING) {
     993                 :                 int i;
     994                 : 
     995              15 :                 result->type = IS_STRING;
     996              15 :                 result->value.str.val = estrndup(op1->value.str.val, op1->value.str.len);
     997              15 :                 result->value.str.len = op1->value.str.len;
     998              83 :                 for (i = 0; i < op1->value.str.len; i++) {
     999              68 :                         result->value.str.val[i] = ~op1->value.str.val[i];
    1000                 :                 }
    1001              15 :                 return SUCCESS;
    1002                 :         }
    1003               1 :         zend_error(E_ERROR, "Unsupported operand types");
    1004               0 :         return FAILURE;                         /* unknown datatype */
    1005                 : }
    1006                 : 
    1007                 : 
    1008                 : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1009             943 : {
    1010                 :         zval op1_copy, op2_copy;
    1011                 :         
    1012             943 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
    1013                 :                 zval *longer, *shorter;
    1014                 :                 char *result_str;
    1015                 :                 int i, result_len;
    1016                 : 
    1017             200 :                 if (op1->value.str.len >= op2->value.str.len) {
    1018             117 :                         longer = op1;
    1019             117 :                         shorter = op2;
    1020                 :                 } else {
    1021              83 :                         longer = op2;
    1022              83 :                         shorter = op1;
    1023                 :                 }
    1024                 : 
    1025             200 :                 result->type = IS_STRING;
    1026             200 :                 result_len = longer->value.str.len;
    1027             200 :                 result_str = estrndup(longer->value.str.val, longer->value.str.len);
    1028             888 :                 for (i = 0; i < shorter->value.str.len; i++) {
    1029             688 :                         result_str[i] |= shorter->value.str.val[i];
    1030                 :                 }
    1031             200 :                 if (result==op1) {
    1032               1 :                         STR_FREE(result->value.str.val);
    1033                 :                 }
    1034             200 :                 result->value.str.val = result_str;
    1035             200 :                 result->value.str.len = result_len;
    1036             200 :                 return SUCCESS;
    1037                 :         }
    1038             743 :         zendi_convert_to_long(op1, op1_copy, result);
    1039             743 :         zendi_convert_to_long(op2, op2_copy, result);
    1040                 : 
    1041             743 :         result->type = IS_LONG;
    1042             743 :         result->value.lval = op1->value.lval | op2->value.lval;
    1043             743 :         return SUCCESS;
    1044                 : }
    1045                 : 
    1046                 : 
    1047                 : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1048            5131 : {
    1049                 :         zval op1_copy, op2_copy;
    1050                 :         
    1051            5131 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
    1052                 :                 zval *longer, *shorter;
    1053                 :                 char *result_str;
    1054                 :                 int i, result_len;
    1055                 : 
    1056             201 :                 if (op1->value.str.len >= op2->value.str.len) {
    1057             117 :                         longer = op1;
    1058             117 :                         shorter = op2;
    1059                 :                 } else {
    1060              84 :                         longer = op2;
    1061              84 :                         shorter = op1;
    1062                 :                 }
    1063                 : 
    1064             201 :                 result->type = IS_STRING;
    1065             201 :                 result_len = shorter->value.str.len;
    1066             201 :                 result_str = estrndup(shorter->value.str.val, shorter->value.str.len);
    1067             888 :                 for (i = 0; i < shorter->value.str.len; i++) {
    1068             687 :                         result_str[i] &= longer->value.str.val[i];
    1069                 :                 }
    1070             201 :                 if (result==op1) {
    1071               1 :                         STR_FREE(result->value.str.val);
    1072                 :                 }
    1073             201 :                 result->value.str.val = result_str;
    1074             201 :                 result->value.str.len = result_len;
    1075             201 :                 return SUCCESS;
    1076                 :         }
    1077                 :         
    1078                 : 
    1079            4930 :         zendi_convert_to_long(op1, op1_copy, result);
    1080            4930 :         zendi_convert_to_long(op2, op2_copy, result);
    1081                 : 
    1082            4930 :         result->type = IS_LONG;
    1083            4930 :         result->value.lval = op1->value.lval & op2->value.lval;
    1084            4930 :         return SUCCESS;
    1085                 : }
    1086                 : 
    1087                 : 
    1088                 : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1089             214 : {
    1090                 :         zval op1_copy, op2_copy;
    1091                 :         
    1092             214 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
    1093                 :                 zval *longer, *shorter;
    1094                 :                 char *result_str;
    1095                 :                 int i, result_len;
    1096                 : 
    1097             202 :                 if (op1->value.str.len >= op2->value.str.len) {
    1098             118 :                         longer = op1;
    1099             118 :                         shorter = op2;
    1100                 :                 } else {
    1101              84 :                         longer = op2;
    1102              84 :                         shorter = op1;
    1103                 :                 }
    1104                 : 
    1105             202 :                 result->type = IS_STRING;
    1106             202 :                 result_len = shorter->value.str.len;
    1107             202 :                 result_str = estrndup(shorter->value.str.val, shorter->value.str.len);
    1108             892 :                 for (i = 0; i < shorter->value.str.len; i++) {
    1109             690 :                         result_str[i] ^= longer->value.str.val[i];
    1110                 :                 }
    1111             202 :                 if (result==op1) {
    1112               1 :                         STR_FREE(result->value.str.val);
    1113                 :                 }
    1114             202 :                 result->value.str.val = result_str;
    1115             202 :                 result->value.str.len = result_len;
    1116             202 :                 return SUCCESS;
    1117                 :         }
    1118                 : 
    1119              12 :         zendi_convert_to_long(op1, op1_copy, result);
    1120              12 :         zendi_convert_to_long(op2, op2_copy, result);   
    1121                 : 
    1122              12 :         result->type = IS_LONG;
    1123              12 :         result->value.lval = op1->value.lval ^ op2->value.lval;
    1124              12 :         return SUCCESS;
    1125                 : }
    1126                 : 
    1127                 : 
    1128                 : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1129            3124 : {
    1130                 :         zval op1_copy, op2_copy;
    1131                 :         
    1132            3124 :         zendi_convert_to_long(op1, op1_copy, result);
    1133            3124 :         zendi_convert_to_long(op2, op2_copy, result);
    1134            3124 :         result->value.lval = op1->value.lval << op2->value.lval;
    1135            3124 :         result->type = IS_LONG;
    1136            3124 :         return SUCCESS;
    1137                 : }
    1138                 : 
    1139                 : 
    1140                 : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1141             219 : {
    1142                 :         zval op1_copy, op2_copy;
    1143                 :         
    1144             219 :         zendi_convert_to_long(op1, op1_copy, result);
    1145             219 :         zendi_convert_to_long(op2, op2_copy, result);
    1146             219 :         result->value.lval = op1->value.lval >> op2->value.lval;
    1147             219 :         result->type = IS_LONG;
    1148             219 :         return SUCCESS;
    1149                 : }
    1150                 : 
    1151                 : 
    1152                 : 
    1153                 : /* must support result==op1 */
    1154                 : ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2)
    1155          723687 : {
    1156          723687 :         result->value.str.len = op1->value.str.len + 1;
    1157          723687 :         result->value.str.val = (char *) erealloc(op1->value.str.val, result->value.str.len+1);
    1158          723687 :     result->value.str.val[result->value.str.len - 1] = (char) op2->value.lval;
    1159          723687 :         result->value.str.val[result->value.str.len] = 0;
    1160          723687 :         result->type = IS_STRING;
    1161          723687 :         return SUCCESS;
    1162                 : }
    1163                 : 
    1164                 : 
    1165                 : /* must support result==op1 */
    1166                 : ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2)
    1167         2315117 : {
    1168         2315117 :         int length = op1->value.str.len + op2->value.str.len;
    1169                 : 
    1170         2315117 :         result->value.str.val = (char *) erealloc(op1->value.str.val, length+1);
    1171         2315117 :     memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
    1172         2315117 :     result->value.str.val[length] = 0;
    1173         2315117 :         result->value.str.len = length;
    1174         2315117 :         result->type = IS_STRING;
    1175         2315117 :         return SUCCESS;
    1176                 : }
    1177                 : 
    1178                 : 
    1179                 : ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1180         2389618 : {
    1181                 :         zval op1_copy, op2_copy;
    1182         2389618 :         int use_copy1 = 0, use_copy2 = 0;
    1183                 : 
    1184         2389618 :         if (op1->type != IS_STRING) {
    1185            1311 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1186                 :         }
    1187         2389618 :         if (op2->type != IS_STRING) {
    1188           34867 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1189                 :         }
    1190                 : 
    1191         2389618 :         if (use_copy1) {
    1192                 :                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1193                 :                  * we have to free it.
    1194                 :                  */
    1195            1311 :                 if (result == op1) {
    1196               7 :                         zval_dtor(op1);
    1197                 :                 }
    1198            1311 :                 op1 = &op1_copy;
    1199                 :         }
    1200         2389618 :         if (use_copy2) {
    1201           34867 :                 op2 = &op2_copy;
    1202                 :         }
    1203         2389618 :         if (result==op1) {      /* special case, perform operations on result */
    1204         1930709 :                 uint res_len = op1->value.str.len + op2->value.str.len;
    1205                 :                 
    1206         1930709 :                 result->value.str.val = erealloc(result->value.str.val, res_len+1);
    1207                 : 
    1208         1930709 :                 memcpy(result->value.str.val+result->value.str.len, op2->value.str.val, op2->value.str.len);
    1209         1930709 :                 result->value.str.val[res_len]=0;
    1210         1930709 :                 result->value.str.len = res_len;
    1211                 :         } else {
    1212          458909 :                 result->value.str.len = op1->value.str.len + op2->value.str.len;
    1213          458909 :                 result->value.str.val = (char *) emalloc(result->value.str.len + 1);
    1214          458909 :                 memcpy(result->value.str.val, op1->value.str.val, op1->value.str.len);
    1215          458909 :                 memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len);
    1216          458909 :                 result->value.str.val[result->value.str.len] = 0;
    1217          458909 :                 result->type = IS_STRING;
    1218                 :         }
    1219         2389618 :         if (use_copy1) {
    1220            1311 :                 zval_dtor(op1);
    1221                 :         }
    1222         2389618 :         if (use_copy2) {
    1223           34867 :                 zval_dtor(op2);
    1224                 :         }
    1225         2389618 :         return SUCCESS;
    1226                 : }
    1227                 : 
    1228                 : 
    1229                 : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1230          636480 : {
    1231                 :         zval op1_copy, op2_copy;
    1232          636480 :         int use_copy1 = 0, use_copy2 = 0;
    1233                 : 
    1234          636480 :         if (op1->type != IS_STRING) {
    1235          412946 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1236                 :         }
    1237          636480 :         if (op2->type != IS_STRING) {
    1238          484178 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1239                 :         }
    1240                 : 
    1241          636480 :         if (use_copy1) {
    1242          412946 :                 op1 = &op1_copy;
    1243                 :         }
    1244          636480 :         if (use_copy2) {
    1245          484178 :                 op2 = &op2_copy;
    1246                 :         }
    1247                 : 
    1248          636480 :         result->value.lval = zend_binary_zval_strcmp(op1, op2);
    1249          636480 :         result->type = IS_LONG;
    1250                 : 
    1251          636480 :         if (use_copy1) {
    1252          412946 :                 zval_dtor(op1);
    1253                 :         }
    1254          636480 :         if (use_copy2) {
    1255          484178 :                 zval_dtor(op2);
    1256                 :         }
    1257          636480 :         return SUCCESS;
    1258                 : }
    1259                 : 
    1260                 : #if HAVE_STRCOLL
    1261                 : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1262              33 : {
    1263                 :         zval op1_copy, op2_copy;
    1264              33 :         int use_copy1 = 0, use_copy2 = 0;
    1265                 : 
    1266              33 :         if (op1->type != IS_STRING) {
    1267               0 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1268                 :         }
    1269              33 :         if (op2->type != IS_STRING) {
    1270               0 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1271                 :         }
    1272                 : 
    1273              33 :         if (use_copy1) {
    1274               0 :                 op1 = &op1_copy;
    1275                 :         }
    1276              33 :         if (use_copy2) {
    1277               0 :                 op2 = &op2_copy;
    1278                 :         }
    1279                 : 
    1280              33 :         result->value.lval = strcoll(op1->value.str.val, op2->value.str.val);
    1281              33 :         result->type = IS_LONG;
    1282                 : 
    1283              33 :         if (use_copy1) {
    1284               0 :                 zval_dtor(op1);
    1285                 :         }
    1286              33 :         if (use_copy2) {
    1287               0 :                 zval_dtor(op2);
    1288                 :         }
    1289              33 :         return SUCCESS;
    1290                 : }
    1291                 : #endif
    1292                 : 
    1293                 : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1294             926 : {
    1295                 :         zval op1_copy, op2_copy;
    1296                 : 
    1297             926 :         op1_copy = *op1;
    1298             926 :         zval_copy_ctor(&op1_copy);
    1299                 : 
    1300             926 :         op2_copy = *op2;
    1301             926 :         zval_copy_ctor(&op2_copy);
    1302                 : 
    1303             926 :         convert_to_double(&op1_copy);
    1304             926 :         convert_to_double(&op2_copy);
    1305                 : 
    1306             926 :         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
    1307                 : 
    1308             926 :         return SUCCESS;
    1309                 : }
    1310                 : 
    1311                 : 
    1312                 : static inline void zend_free_obj_get_result(zval *op)
    1313        12578432 : {
    1314        12578432 :         if (op) {
    1315             421 :                 if (op->refcount == 0) {
    1316               1 :                         zval_dtor(op);
    1317               1 :                         FREE_ZVAL(op);
    1318                 :                 } else {
    1319             420 :                         zval_ptr_dtor(&op);
    1320                 :                 }
    1321                 :         }
    1322        12578432 : }
    1323                 : 
    1324                 : #define COMPARE_RETURN_AND_FREE(retval) \
    1325                 :                         zend_free_obj_get_result(op1_free); \
    1326                 :                         zend_free_obj_get_result(op2_free); \
    1327                 :                         return retval;
    1328                 : 
    1329                 : ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1330         6289264 : {
    1331                 :         zval op1_copy, op2_copy;
    1332                 :         zval *op1_free, *op2_free;
    1333         6289264 :         int op1_obj = Z_TYPE_P(op1) == IS_OBJECT;
    1334         6289264 :         int op2_obj = Z_TYPE_P(op2) == IS_OBJECT;
    1335                 :         int eq_comp = op1_obj && op2_obj && (Z_OBJ_HANDLER_P(op1,compare_objects) 
    1336         6289264 :                                           == Z_OBJ_HANDLER_P(op2,compare_objects));
    1337                 : 
    1338         6289373 :         if (op1_obj && !eq_comp) {
    1339             269 :                 if (Z_TYPE_P(op2) == IS_NULL) {
    1340              48 :                         ZVAL_LONG(result, 1);
    1341              48 :                         return SUCCESS;
    1342             221 :                 } else if (Z_OBJ_HT_P(op1)->get) {
    1343               1 :                         op1 = op1_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
    1344             327 :                 } else if (!op2_obj && Z_OBJ_HT_P(op1)->cast_object) {
    1345             219 :                         ALLOC_INIT_ZVAL(op1_free);
    1346             219 :                         if (Z_OBJ_HT_P(op1)->cast_object(op1, op1_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
    1347             112 :                                 op2_free = NULL;
    1348             112 :                                 ZVAL_LONG(result, 1);
    1349             112 :                                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1350                 :                         }
    1351             107 :                         op1 = op1_free;
    1352                 :                 } else {
    1353               1 :                         op1_free = NULL;
    1354                 :                 }
    1355             109 :                 op1_obj = Z_TYPE_P(op1) == IS_OBJECT;
    1356             109 :                 eq_comp = op1_obj && op2_obj && (Z_OBJ_HANDLER_P(op1,compare_objects) 
    1357                 :                                           == Z_OBJ_HANDLER_P(op2,compare_objects));
    1358                 :         } else {
    1359         6288995 :                 op1_free = NULL;
    1360                 :         }
    1361         6289199 :         if (op2_obj && !eq_comp) {
    1362             217 :                 if (Z_TYPE_P(op1) == IS_NULL) {
    1363              15 :                         op2_free = NULL;
    1364              15 :                         ZVAL_LONG(result, -1);
    1365              15 :                         COMPARE_RETURN_AND_FREE(SUCCESS);
    1366             202 :                 } else if (Z_OBJ_HT_P(op2)->get) {
    1367               0 :                         op2 = op2_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
    1368             296 :                 } else if (!op1_obj && Z_OBJ_HT_P(op2)->cast_object) {
    1369             201 :                         ALLOC_INIT_ZVAL(op2_free);
    1370             201 :                         if (Z_OBJ_HT_P(op2)->cast_object(op2, op2_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
    1371             107 :                                 ZVAL_LONG(result, -1);
    1372             107 :                                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1373                 :                         }
    1374              94 :                         op2 = op2_free;
    1375                 :                 } else {
    1376               1 :                         op2_free = NULL;
    1377                 :                 }
    1378              95 :                 op2_obj = Z_TYPE_P(op2) == IS_OBJECT;
    1379              95 :                 eq_comp = op1_obj && op2_obj && (Z_OBJ_HANDLER_P(op1,compare_objects) 
    1380                 :                                           == Z_OBJ_HANDLER_P(op2,compare_objects));
    1381                 :         } else {
    1382         6288887 :                 op2_free = NULL;
    1383                 :         }
    1384                 : 
    1385         6288982 :         if ((Z_TYPE_P(op1) == IS_NULL && Z_TYPE_P(op2) == IS_STRING)
    1386                 :                 || (Z_TYPE_P(op2) == IS_NULL && Z_TYPE_P(op1) == IS_STRING)) {
    1387             225 :                 if (Z_TYPE_P(op1) == IS_NULL) {
    1388              96 :                         ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1389              96 :                         COMPARE_RETURN_AND_FREE(SUCCESS);
    1390                 :                 } else {
    1391             129 :                         ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
    1392             129 :                         COMPARE_RETURN_AND_FREE(SUCCESS);
    1393                 :                 }
    1394                 :         }
    1395                 :                 
    1396         6288757 :         if (op1->type == IS_STRING && op2->type == IS_STRING) {
    1397          796849 :                 zendi_smart_strcmp(result, op1, op2);
    1398          796849 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1399                 :         }
    1400                 : 
    1401         5491908 :         if (Z_TYPE_P(op1) == IS_BOOL || Z_TYPE_P(op2) == IS_BOOL
    1402                 :                 || Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op2) == IS_NULL) {
    1403            8148 :                 zendi_convert_to_boolean(op1, op1_copy, result);
    1404            8148 :                 zendi_convert_to_boolean(op2, op2_copy, result);
    1405            8148 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1406            8148 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1407                 :         }
    1408                 : 
    1409                 :         /* If both are objects sharing the same comparision handler then use is */
    1410         5483760 :         if (eq_comp) {
    1411             383 :                 if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
    1412                 :                         /* object handles are identical, apprently this is the same object */
    1413              23 :                         ZVAL_LONG(result, 0);
    1414              23 :                         COMPARE_RETURN_AND_FREE(SUCCESS);
    1415                 :                 }
    1416             360 :                 ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC));
    1417             360 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1418                 :         }
    1419                 : 
    1420         5483377 :         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1421         5483377 :         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1422                 : 
    1423         5483377 :         if (Z_TYPE_P(op1) == IS_LONG && Z_TYPE_P(op2) == IS_LONG) {
    1424         5405742 :                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1425         5405742 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1426                 :         }
    1427           77635 :         if ((Z_TYPE_P(op1) == IS_DOUBLE || Z_TYPE_P(op1) == IS_LONG)
    1428                 :                 && (Z_TYPE_P(op2) == IS_DOUBLE || Z_TYPE_P(op2) == IS_LONG)) {
    1429           76791 :                 Z_DVAL_P(result) = (Z_TYPE_P(op1) == IS_LONG ? (double) Z_LVAL_P(op1) : Z_DVAL_P(op1)) - (Z_TYPE_P(op2) == IS_LONG ? (double) Z_LVAL_P(op2) : Z_DVAL_P(op2));
    1430           76791 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1431           76791 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1432                 :         }
    1433             844 :         if (Z_TYPE_P(op1)==IS_ARRAY && Z_TYPE_P(op2)==IS_ARRAY) {
    1434             293 :                 zend_compare_arrays(result, op1, op2 TSRMLS_CC);
    1435             293 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1436                 :         }
    1437                 : 
    1438             551 :         if (Z_TYPE_P(op1)==IS_ARRAY) {
    1439             271 :                 ZVAL_LONG(result, 1);
    1440             271 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1441                 :         }
    1442             280 :         if (Z_TYPE_P(op2)==IS_ARRAY) {
    1443             280 :                 ZVAL_LONG(result, -1);
    1444             280 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1445                 :         }
    1446               0 :         if (Z_TYPE_P(op1)==IS_OBJECT) {
    1447               0 :                 ZVAL_LONG(result, 1);
    1448               0 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1449                 :         }
    1450               0 :         if (Z_TYPE_P(op2)==IS_OBJECT) {
    1451               0 :                 ZVAL_LONG(result, -1);
    1452               0 :                 COMPARE_RETURN_AND_FREE(SUCCESS);
    1453                 :         }
    1454                 : 
    1455               0 :         ZVAL_BOOL(result, 0);
    1456               0 :         COMPARE_RETURN_AND_FREE(FAILURE);
    1457                 : }
    1458                 : 
    1459                 : 
    1460                 : static int hash_zval_identical_function(const zval **z1, const zval **z2)
    1461             445 : {
    1462                 :         zval result;
    1463                 :         TSRMLS_FETCH();
    1464                 : 
    1465                 :         /* is_identical_function() returns 1 in case of identity and 0 in case
    1466                 :          * of a difference;
    1467                 :          * whereas this comparison function is expected to return 0 on identity,
    1468                 :          * and non zero otherwise.
    1469                 :          */
    1470             445 :         if (is_identical_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    1471               0 :                 return 1;
    1472                 :         }
    1473             445 :         return !result.value.lval;
    1474                 : }
    1475                 : 
    1476                 : 
    1477                 : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1478         1918208 : {
    1479         1918208 :         result->type = IS_BOOL;
    1480         1918208 :         if (op1->type != op2->type) {
    1481         1258299 :                 result->value.lval = 0;
    1482         1258299 :                 return SUCCESS;
    1483                 :         }
    1484          659909 :         switch (op1->type) {
    1485                 :                 case IS_NULL:
    1486             198 :                         result->value.lval = (op2->type==IS_NULL);
    1487             198 :                         break;
    1488                 :                 case IS_BOOL:
    1489                 :                 case IS_LONG:
    1490                 :                 case IS_RESOURCE:
    1491          651124 :                         result->value.lval = (op1->value.lval == op2->value.lval);
    1492          651124 :                         break;
    1493                 :                 case IS_DOUBLE:
    1494             186 :                         result->value.lval = (op1->value.dval == op2->value.dval);
    1495             186 :                         break;
    1496                 :                 case IS_STRING:
    1497            8600 :                         if ((op1->value.str.len == op2->value.str.len)
    1498                 :                                 && (!memcmp(op1->value.str.val, op2->value.str.val, op1->value.str.len))) {
    1499             256 :                                 result->value.lval = 1;
    1500                 :                         } else {
    1501            8088 :                                 result->value.lval = 0;
    1502                 :                         }
    1503            8344 :                         break;
    1504                 :                 case IS_ARRAY:
    1505              40 :                         if (zend_hash_compare(op1->value.ht, op2->value.ht, (compare_func_t) hash_zval_identical_function, 1 TSRMLS_CC)==0) {
    1506              33 :                                 result->value.lval = 1;
    1507                 :                         } else {
    1508               7 :                                 result->value.lval = 0;
    1509                 :                         }
    1510              40 :                         break;
    1511                 :                 case IS_OBJECT:
    1512              17 :                         if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
    1513              17 :                                 if (EG(ze1_compatibility_mode)) {
    1514               0 :                                         zend_compare_objects(result, op1, op2 TSRMLS_CC);
    1515                 :                                         /* comparison returns 0 in case of equality and
    1516                 :                                          * 1 in case of ineqaulity, we need to reverse it
    1517                 :                                          */
    1518               0 :                                         result->value.lval = !result->value.lval;
    1519                 :                                 } else {
    1520              17 :                                         result->value.lval = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
    1521                 :                                 }
    1522                 :                         } else {
    1523               0 :                                 result->value.lval = 0;
    1524                 :                         }
    1525              17 :                         break;
    1526                 :                 default:
    1527               0 :                         ZVAL_BOOL(result, 0);
    1528               0 :                         return FAILURE;
    1529                 :         }
    1530          659909 :         return SUCCESS;
    1531                 : }
    1532                 : 
    1533                 : 
    1534                 : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1535          345560 : {
    1536          345560 :    result->type = IS_BOOL;
    1537          345560 :    if (is_identical_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1538               0 :           return FAILURE;
    1539                 :    }
    1540          345560 :    result->value.lval = !result->value.lval;
    1541          345560 :    return SUCCESS;
    1542                 : }
    1543                 : 
    1544                 : 
    1545                 : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1546         1540315 : {
    1547         1540315 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1548               0 :                 return FAILURE;
    1549                 :         }
    1550         1540315 :         convert_to_boolean(result);
    1551         1540315 :         if (result->value.lval == 0) {
    1552          421039 :                 result->value.lval = 1;
    1553                 :         } else {
    1554         1119276 :                 result->value.lval = 0;
    1555                 :         }
    1556         1540315 :         return SUCCESS;
    1557                 : }
    1558                 : 
    1559                 : 
    1560                 : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1561          119951 : {
    1562          119951 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1563               0 :                 return FAILURE;
    1564                 :         }
    1565          119951 :         convert_to_boolean(result);
    1566          119951 :         if (result->value.lval) {
    1567           19730 :                 result->value.lval = 1;
    1568                 :         } else {
    1569          100221 :                 result->value.lval = 0;
    1570                 :         }
    1571          119951 :         return SUCCESS;
    1572                 : }
    1573                 : 
    1574                 : 
    1575                 : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1576         4310305 : {
    1577         4310305 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1578               0 :                 return FAILURE;
    1579                 :         }
    1580         4310305 :         if (result->type == IS_LONG) {
    1581         4310305 :                 result->type = IS_BOOL;
    1582         4310305 :                 if (result->value.lval < 0) {
    1583         3952625 :                         result->value.lval = 1;
    1584                 :                 } else {
    1585          357680 :                         result->value.lval = 0;
    1586                 :                 }
    1587         4310305 :                 return SUCCESS;
    1588                 :         }
    1589               0 :         if (result->type == IS_DOUBLE) {
    1590               0 :                 result->type = IS_BOOL;
    1591               0 :                 if (result->value.dval < 0) {
    1592               0 :                         result->value.lval = 1;
    1593                 :                 } else {
    1594               0 :                         result->value.lval = 0;
    1595                 :                 }
    1596               0 :                 return SUCCESS;
    1597                 :         }
    1598               0 :         zend_error(E_ERROR, "Unsupported operand types");
    1599               0 :         return FAILURE;
    1600                 : }
    1601                 : 
    1602                 : 
    1603                 : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
    1604          312831 : {
    1605          312831 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1606               0 :                 return FAILURE;
    1607                 :         }
    1608          312831 :         if (result->type == IS_LONG) {
    1609          312831 :                 result->type = IS_BOOL;
    1610          312831 :                 if (result->value.lval <= 0) {
    1611          259172 :                         result->value.lval = 1;
    1612                 :                 } else {
    1613           53659 :                         result->value.lval = 0;
    1614                 :                 }
    1615          312831 :                 return SUCCESS;
    1616                 :         }
    1617               0 :         if (result->type == IS_DOUBLE) {
    1618               0 :                 result->type = IS_BOOL;
    1619               0 :                 if (result->value.dval <= 0) {
    1620               0 :                         result->value.lval = 1;
    1621                 :                 } else {
    1622               0 :                         result->value.lval = 0;
    1623                 :                 }
    1624               0 :                 return SUCCESS;
    1625                 :         }
    1626               0 :         zend_error(E_ERROR, "Unsupported operand types");
    1627               0 :         return FAILURE;
    1628                 : }
    1629                 : 
    1630                 : 
    1631                 : ZEND_API zend_bool instanceof_function_ex(zend_class_entry *instance_ce, zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC)
    1632           27826 : {
    1633                 :         zend_uint i;
    1634                 : 
    1635           41641 :         for (i=0; i<instance_ce->num_interfaces; i++) {
    1636           15406 :                 if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) {
    1637            1591 :                         return 1;
    1638                 :                 }
    1639                 :         }
    1640           26235 :         if (!interfaces_only) {
    1641           72524 :                 while (instance_ce) {
    1642           30117 :                         if (instance_ce == ce) {
    1643           10061 :                                 return 1;
    1644                 :                         }
    1645           20056 :                         instance_ce = instance_ce->parent;
    1646                 :                 }
    1647                 :         }
    1648                 : 
    1649           16174 :         return 0;
    1650                 : }
    1651                 : 
    1652                 : ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce, zend_class_entry *ce TSRMLS_DC)
    1653           27580 : {
    1654           27580 :         return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
    1655                 : }
    1656                 : 
    1657                 : #define LOWER_CASE 1
    1658                 : #define UPPER_CASE 2
    1659                 : #define NUMERIC 3
    1660                 : 
    1661                 : 
    1662                 : static void increment_string(zval *str)
    1663              40 : {
    1664              40 :     int carry=0;
    1665              40 :     int pos=str->value.str.len-1;
    1666              40 :     char *s=str->value.str.val;
    1667                 :     char *t;
    1668              40 :     int last=0; /* Shut up the compiler warning */
    1669                 :     int ch;
    1670                 :     
    1671              40 :         if (str->value.str.len == 0) {
    1672               1 :                 STR_FREE(str->value.str.val);
    1673               1 :                 str->value.str.val = estrndup("1", sizeof("1")-1);
    1674               1 :                 str->value.str.len = 1;
    1675               1 :                 return;
    1676                 :         }
    1677                 : 
    1678              82 :         while (pos >= 0) {
    1679              43 :         ch = s[pos];
    1680              74 :         if (ch >= 'a' && ch <= 'z') {
    1681              31 :             if (ch == 'z') {
    1682               2 :                 s[pos] = 'a';
    1683               2 :                 carry=1;
    1684                 :             } else {
    1685              29 :                 s[pos]++;
    1686              29 :                 carry=0;
    1687                 :             }
    1688              31 :             last=LOWER_CASE;
    1689              18 :         } else if (ch >= 'A' && ch <= 'Z') {
    1690               6 :             if (ch == 'Z') {
    1691               0 :                 s[pos] = 'A';
    1692               0 :                 carry=1;
    1693                 :             } else {
    1694               6 :                 s[pos]++;
    1695               6 :                 carry=0;
    1696                 :             }
    1697               6 :             last=UPPER_CASE;
    1698               8 :         } else if (ch >= '0' && ch <= '9') {
    1699               2 :             if (ch == '9') {
    1700               2 :                 s[pos] = '0';
    1701               2 :                 carry=1;
    1702                 :             } else {
    1703               0 :                 s[pos]++;
    1704               0 :                 carry=0;
    1705                 :             }
    1706               2 :             last = NUMERIC;
    1707                 :         } else {
    1708               4 :             carry=0;
    1709               4 :             break;
    1710                 :         }
    1711              39 :         if (carry == 0) {
    1712              35 :             break;
    1713                 :         }
    1714               4 :         pos--;
    1715                 :     }
    1716                 : 
    1717              39 :     if (carry) {
    1718               0 :         t = (char *) emalloc(str->value.str.len+1+1);
    1719               0 :         memcpy(t+1, str->value.str.val, str->value.str.len);
    1720               0 :         str->value.str.len++;
    1721               0 :         t[str->value.str.len] = '\0';
    1722               0 :         switch (last) {
    1723                 :             case NUMERIC:
    1724               0 :                 t[0] = '1';
    1725               0 :                 break;
    1726                 :             case UPPER_CASE:
    1727               0 :                 t[0] = 'A';
    1728               0 :                 break;
    1729                 :             case LOWER_CASE:
    1730               0 :                 t[0] = 'a';
    1731                 :                 break;
    1732                 :         }
    1733               0 :         STR_FREE(str->value.str.val);
    1734               0 :         str->value.str.val = t;
    1735                 :     }
    1736                 : }
    1737                 : 
    1738                 : 
    1739                 : ZEND_API int increment_function(zval *op1)
    1740         4311474 : {
    1741         4311474 :         switch (op1->type) {
    1742                 :                 case IS_LONG:
    1743         4311296 :                         if (op1->value.lval == LONG_MAX) {
    1744                 :                                 /* switch to double */
    1745               2 :                                 double d = (double)op1->value.lval;
    1746               2 :                                 ZVAL_DOUBLE(op1, d+1);
    1747                 :                         } else {
    1748         4311294 :                         op1->value.lval++;
    1749                 :                         } 
    1750         4311296 :                         break;
    1751                 :                 case IS_DOUBLE:
    1752               1 :                         op1->value.dval = op1->value.dval + 1;
    1753               1 :                         break;
    1754                 :                 case IS_NULL:
    1755              17 :                         op1->value.lval = 1;
    1756              17 :                         op1->type = IS_LONG;
    1757              17 :                         break;
    1758                 :                 case IS_STRING: {
    1759                 :                                 long lval;
    1760                 :                                 double dval;
    1761             155 :                                 char *strval = op1->value.str.val;
    1762                 : 
    1763             155 :                                 switch (is_numeric_string(strval, op1->value.str.len, &lval, &dval, 0)) {
    1764                 :                                         case IS_LONG:
    1765             108 :                                                 if (lval == LONG_MAX) {
    1766                 :                                                         /* switch to double */
    1767               1 :                                                         double d = (double)lval;
    1768               1 :                                                         ZVAL_DOUBLE(op1, d+1);
    1769                 :                                                 } else {
    1770             107 :                                                 op1->value.lval = lval+1;
    1771             107 :                                                 op1->type = IS_LONG;
    1772                 :                                                 }
    1773             108 :                                                 efree(strval); /* should never be empty_string */
    1774             108 :                                                 break;
    1775                 :                                         case IS_DOUBLE:
    1776               7 :                                                 op1->value.dval = dval+1;
    1777               7 :                                                 op1->type = IS_DOUBLE;
    1778               7 :                                                 efree(strval); /* should never be empty_string */
    1779               7 :                                                 break;
    1780                 :                                         default:
    1781                 :                                                 /* Perl style string increment */
    1782              40 :                                                 increment_string(op1);
    1783                 :                                                 break;
    1784                 :                                 }
    1785                 :                         }
    1786             155 :                         break;
    1787                 :                 default:
    1788               5 :                         return FAILURE;
    1789                 :         }
    1790         4311469 :         return SUCCESS;
    1791                 : }
    1792                 : 
    1793                 : 
    1794                 : ZEND_API int decrement_function(zval *op1)
    1795          910617 : {
    1796                 :         long lval;
    1797                 :         double dval;
    1798                 :         
    1799          910617 :         switch (op1->type) {
    1800                 :                 case IS_LONG:
    1801          561592 :                         if (op1->value.lval == LONG_MIN) {
    1802               1 :                                 double d = (double)op1->value.lval;
    1803               1 :                                 ZVAL_DOUBLE(op1, d-1);
    1804                 :                         } else {
    1805          561591 :                         op1->value.lval--;
    1806                 :                         }
    1807          561592 :                         break;
    1808                 :                 case IS_DOUBLE:
    1809          348986 :                         op1->value.dval = op1->value.dval - 1;
    1810          348986 :                         break;
    1811                 :                 case IS_STRING:         /* Like perl we only support string increment */
    1812              33 :                         if (op1->value.str.len == 0) { /* consider as 0 */
    1813               1 :                                 STR_FREE(op1->value.str.val);
    1814               1 :                                 op1->value.lval = -1;
    1815               1 :                                 op1->type = IS_LONG;
    1816               1 :                                 break;
    1817                 :                         }
    1818              32 :                         switch (is_numeric_string(op1->value.str.val, op1->value.str.len, &lval, &dval, 0)) {
    1819                 :                                 case IS_LONG:
    1820               8 :                                         STR_FREE(op1->value.str.val);
    1821               8 :                                         if (lval == LONG_MIN) {
    1822               1 :                                                 double d = (double)lval;
    1823               1 :                                                 ZVAL_DOUBLE(op1, d-1);
    1824                 :                                         } else {
    1825               7 :                                                 op1->value.lval = lval-1;
    1826               7 :                                                 op1->type = IS_LONG;
    1827                 :                                         }
    1828               8 :                                         break;
    1829                 :                                 case IS_DOUBLE:
    1830               7 :                                         STR_FREE(op1->value.str.val);
    1831               7 :                                         op1->value.dval = dval - 1;
    1832               7 :                                         op1->type = IS_DOUBLE;
    1833                 :                                         break;
    1834                 :                         }
    1835              32 :                         break;
    1836                 :                 default:
    1837               6 :                         return FAILURE;
    1838                 :         }
    1839                 : 
    1840          910611 :         return SUCCESS;
    1841                 : }
    1842                 : 
    1843                 : 
    1844                 : ZEND_API int zval_is_true(zval *op)
    1845            3378 : {
    1846            3378 :         convert_to_boolean(op);
    1847            3378 :         return (op->value.lval ? 1 : 0);
    1848                 : }
    1849                 : 
    1850                 : #ifdef ZEND_USE_TOLOWER_L
    1851                 : ZEND_API void zend_update_current_locale(void)
    1852                 : {
    1853                 :         current_locale = _get_current_locale();
    1854                 : }
    1855                 : #endif
    1856                 : 
    1857                 : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length)
    1858        46463204 : {
    1859        46463204 :         register unsigned char *str = (unsigned char*)source;
    1860        46463204 :         register unsigned char *result = (unsigned char*)dest;
    1861        46463204 :         register unsigned char *end = str + length;
    1862                 : 
    1863       709643047 :         while (str < end) {
    1864       616716639 :                 *result++ = zend_tolower((int)*str++);
    1865                 :         }
    1866        46463204 :         *result = '\0';
    1867                 : 
    1868        46463204 :         return dest;
    1869                 : }
    1870                 :         
    1871                 : ZEND_API void zend_str_tolower(char *str, unsigned int length)
    1872         1492009 : {
    1873         1492009 :         register unsigned char *p = (unsigned char*)str;
    1874         1492009 :         register unsigned char *end = p + length;
    1875                 : 
    1876        16622628 :         while (p < end) {
    1877        13638610 :                 *p = zend_tolower((int)*p);
    1878        13638610 :                 p++;
    1879                 :         }
    1880         1492009 : }
    1881                 : 
    1882                 : ZEND_API int zend_binary_strcmp(char *s1, uint len1, char *s2, uint len2)
    1883         1985650 : {
    1884                 :         int retval;
    1885                 :         
    1886         1985650 :         retval = memcmp(s1, s2, MIN(len1, len2));
    1887         1985650 :         if (!retval) {
    1888          832448 :                 return (len1 - len2);
    1889                 :         } else {
    1890         1153202 :                 return retval;
    1891                 :         }
    1892                 : }
    1893                 : 
    1894                 : ZEND_API int zend_binary_strncmp(char *s1, uint len1, char *s2, uint len2, uint length)
    1895            9808 : {
    1896                 :         int retval;
    1897                 :         
    1898            9808 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    1899            9808 :         if (!retval) {
    1900            9576 :                 return (MIN(length, len1) - MIN(length, len2));
    1901                 :         } else {
    1902             232 :                 return retval;
    1903                 :         }
    1904                 : }
    1905                 : 
    1906                 : 
    1907                 : ZEND_API int zend_binary_strcasecmp(char *s1, uint len1, char *s2, uint len2)
    1908           26892 : {
    1909                 :         int len;
    1910                 :         int c1, c2;
    1911                 : 
    1912           26892 :         len = MIN(len1, len2);
    1913                 : 
    1914          112083 :         while (len--) {
    1915           84693 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    1916           84693 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    1917           84693 :                 if (c1 != c2) {
    1918           26394 :                         return c1 - c2;
    1919                 :                 }
    1920                 :         }
    1921                 : 
    1922             498 :         return len1 - len2;
    1923                 : }
    1924                 : 
    1925                 : 
    1926                 : ZEND_API int zend_binary_strncasecmp(char *s1, uint len1, char *s2, uint len2, uint length)
    1927           13788 : {
    1928                 :         int len;
    1929                 :         int c1, c2;
    1930                 : 
    1931           13788 :         len = MIN(length, MIN(len1, len2));
    1932                 : 
    1933           33569 :         while (len--) {
    1934            6234 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    1935            6234 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    1936            6234 :                 if (c1 != c2) {
    1937             241 :                         return c1 - c2;
    1938                 :                 }
    1939                 :         }
    1940                 : 
    1941           13547 :         return MIN(length, len1) - MIN(length, len2);
    1942                 : }
    1943                 : 
    1944                 : 
    1945                 : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2)
    1946         1985425 : {
    1947         1985425 :         return zend_binary_strcmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
    1948                 : }
    1949                 : 
    1950                 : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3)
    1951            9781 : {
    1952            9781 :         return zend_binary_strncmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len, s3->value.lval);
    1953                 : }
    1954                 : 
    1955                 : 
    1956                 : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2)
    1957            1030 : {
    1958            1030 :         return zend_binary_strcasecmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len);
    1959                 : }
    1960                 : 
    1961                 : 
    1962                 : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3)
    1963           13759 : {
    1964           13759 :         return zend_binary_strncasecmp(s1->value.str.val, s1->value.str.len, s2->value.str.val, s2->value.str.len, s3->value.lval);
    1965                 : }
    1966                 : 
    1967                 : 
    1968                 : ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2)
    1969          796849 : {
    1970                 :         int ret1, ret2;
    1971                 :         long lval1, lval2;
    1972                 :         double dval1, dval2;
    1973                 :         
    1974         1096899 :         if ((ret1=is_numeric_string(s1->value.str.val, s1->value.str.len, &lval1, &dval1, 0)) &&
    1975                 :                 (ret2=is_numeric_string(s2->value.str.val, s2->value.str.len, &lval2, &dval2, 0))) {
    1976          400071 :                 if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
    1977          100021 :                         if (ret1!=IS_DOUBLE) {
    1978              24 :                                 dval1 = (double) lval1;
    1979           99997 :                         } else if (ret2!=IS_DOUBLE) {
    1980              20 :                                 dval2 = (double) lval2;
    1981           99977 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    1982                 :                                 /* Both values overflowed and have the same sign,
    1983                 :                                  * so a numeric comparison would be inaccurate */
    1984               0 :                                 goto string_cmp;
    1985                 :                         }
    1986          100021 :                         result->value.dval = dval1 - dval2;
    1987          100021 :                         result->value.lval = ZEND_NORMALIZE_BOOL(result->value.dval);
    1988          100021 :                         result->type = IS_LONG;
    1989                 :                 } else { /* they both have to be long's */
    1990          200029 :                         result->value.lval = lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0);
    1991          200029 :                         result->type = IS_LONG;
    1992                 :                 }
    1993                 :         } else {
    1994          496799 : string_cmp:
    1995          496799 :                 result->value.lval = zend_binary_zval_strcmp(s1, s2);
    1996          496799 :                 result->value.lval = ZEND_NORMALIZE_BOOL(result->value.lval);
    1997          496799 :                 result->type = IS_LONG;
    1998                 :         }
    1999                 :         return; 
    2000                 : }
    2001                 : 
    2002                 : 
    2003                 : static int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC)
    2004             504 : {
    2005                 :         zval result;
    2006                 : 
    2007             504 :         if (compare_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    2008               0 :                 return 1;
    2009                 :         }
    2010             504 :         return result.value.lval;
    2011                 : }
    2012                 : 
    2013                 : ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC)
    2014             312 : {
    2015             312 :         return zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    2016                 : }
    2017                 : 
    2018                 : 
    2019                 : 
    2020                 : ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC)
    2021             293 : {
    2022             293 :         result->type = IS_LONG;
    2023             293 :         result->value.lval = zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    2024             293 : }
    2025                 : 
    2026                 : 
    2027                 : ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC)
    2028             293 : {
    2029             293 :         zend_compare_symbol_tables(result, a1->value.ht, a2->value.ht TSRMLS_CC);
    2030             293 : }
    2031                 : 
    2032                 : 
    2033                 : ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC)
    2034               0 : {
    2035               0 :         result->type = IS_LONG;
    2036                 : 
    2037               0 :         if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {
    2038               0 :                 result->value.lval = 0;
    2039               0 :                 return;
    2040                 :         }
    2041                 : 
    2042               0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2043               0 :                 result->value.lval = 1;
    2044                 :         } else {
    2045               0 :                 result->value.lval = Z_OBJ_HT_P(o1)->compare_objects(o1, o2 TSRMLS_CC);
    2046                 :         }
    2047                 : }
    2048                 : 
    2049                 : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC)
    2050           16729 : {
    2051                 :         TSRMLS_FETCH();
    2052                 : 
    2053           16729 :         op->value.str.len = zend_spprintf(&op->value.str.val, 0, "%.*G", (int) EG(precision), (double)op->value.dval);
    2054           16729 : }
    2055                 : 
    2056                 : /*
    2057                 :  * Local variables:
    2058                 :  * tab-width: 4
    2059                 :  * c-basic-offset: 4
    2060                 :  * indent-tabs-mode: t
    2061                 :  * End:
    2062                 :  */

Generated by: LTP GCOV extension version 1.5

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

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