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

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:26:54 +0000 (3 days ago)

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