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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_HEAD/Zend - zend_operators.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 1401
Code covered: 77.9 % Executed lines: 1091
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 281669 2009-06-04 18:18:47Z 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                 : #include "unicode/uchar.h"
      35                 : #include "unicode/ucol.h"
      36                 : 
      37                 : #define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
      38                 : 
      39                 : #if ZEND_USE_TOLOWER_L
      40                 : #include <locale.h>
      41                 : static _locale_t current_locale = NULL;
      42                 : /* this is true global! may lead to strange effects on ZTS, but so may setlocale() */
      43                 : #define zend_tolower(c) _tolower_l(c, current_locale)
      44                 : #else
      45                 : #define zend_tolower(c) tolower(c)
      46                 : #endif
      47                 : 
      48                 : #define TYPE_PAIR(t1,t2) (((t1) << 4) | (t2))
      49                 : 
      50                 : ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
      51           51031 : {
      52                 :         int retval;
      53                 : 
      54           51031 :         if (!str_len) {
      55           33819 :                 str_len = strlen(str);
      56                 :         }
      57           51031 :         retval = strtol(str, NULL, 0);
      58           51031 :         if (str_len>0) {
      59           34213 :                 switch (str[str_len-1]) {
      60                 :                         case 'g':
      61                 :                         case 'G':
      62               0 :                                 retval *= 1024;
      63                 :                                 /* break intentionally missing */
      64                 :                         case 'm':
      65                 :                         case 'M':
      66               0 :                                 retval *= 1024;
      67                 :                                 /* break intentionally missing */
      68                 :                         case 'k':
      69                 :                         case 'K':
      70               0 :                                 retval *= 1024;
      71                 :                                 break;
      72                 :                 }
      73                 :         }
      74           51031 :         return retval;
      75                 : }
      76                 : /* }}} */
      77                 : 
      78                 : ZEND_API long zend_atol(const char *str, int str_len) /* {{{ */
      79         1037672 : {
      80                 :         long retval;
      81                 : 
      82         1037672 :         if (!str_len) {
      83           33711 :                 str_len = strlen(str);
      84                 :         }
      85         1037672 :         retval = strtol(str, NULL, 0);
      86         1037672 :         if (str_len>0) {
      87         1003961 :                 switch (str[str_len-1]) {
      88                 :                         case 'g':
      89                 :                         case 'G':
      90               4 :                                 retval *= 1024;
      91                 :                                 /* break intentionally missing */
      92                 :                         case 'm':
      93                 :                         case 'M':
      94           50986 :                                 retval *= 1024;
      95                 :                                 /* break intentionally missing */
      96                 :                         case 'k':
      97                 :                         case 'K':
      98           67994 :                                 retval *= 1024;
      99                 :                                 break;
     100                 :                 }
     101                 :         }
     102         1037672 :         return retval;
     103                 : }
     104                 : /* }}} */
     105                 : 
     106                 : ZEND_API double zend_string_to_double(const char *number, zend_uint length) /* {{{ */
     107               0 : {
     108               0 :         double divisor = 10.0;
     109               0 :         double result = 0.0;
     110                 :         double exponent;
     111               0 :         const char *end = number+length;
     112               0 :         const char *digit = number;
     113                 : 
     114               0 :         if (!length) {
     115               0 :                 return result;
     116                 :         }
     117                 : 
     118               0 :         while (digit < end) {
     119               0 :                 if ((*digit <= '9' && *digit >= '0')) {
     120               0 :                         result *= 10;
     121               0 :                         result += *digit - '0';
     122               0 :                 } else if (*digit == '.') {
     123               0 :                         digit++;
     124               0 :                         break;
     125               0 :                 } else if (toupper(*digit) == 'E') {
     126               0 :                         exponent = (double) atoi(digit+1);
     127               0 :                         result *= pow(10.0, exponent);
     128               0 :                         return result;
     129                 :                 } else {
     130               0 :                         return result;
     131                 :                 }
     132               0 :                 digit++;
     133                 :         }
     134                 : 
     135               0 :         while (digit < end) {
     136               0 :                 if ((*digit <= '9' && *digit >= '0')) {
     137               0 :                         result += (*digit - '0') / divisor;
     138               0 :                         divisor *= 10;
     139               0 :                 } else if (toupper(*digit) == 'E') {
     140               0 :                         exponent = (double) atoi(digit+1);
     141               0 :                         result *= pow(10.0, exponent);
     142               0 :                         return result;
     143                 :                 } else {
     144               0 :                         return result;
     145                 :                 }
     146               0 :                 digit++;
     147                 :         }
     148               0 :         return result;
     149                 : }
     150                 : /* }}} */
     151                 : 
     152                 : ZEND_API int convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
     153          208102 : {
     154          208102 :         switch (Z_TYPE_P(op)) {
     155                 :                 case IS_STRING:
     156                 :                         {
     157                 :                                 char *strval;
     158                 : 
     159               7 :                                 strval = Z_STRVAL_P(op);
     160               7 :                                 switch ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1))) {
     161                 :                                         case IS_DOUBLE:
     162                 :                                         case IS_LONG:
     163               7 :                                                 break;
     164                 :                                         default:
     165               0 :                                                 Z_LVAL_P(op) = strtol(Z_STRVAL_P(op), NULL, 10);
     166               0 :                                                 Z_TYPE_P(op) = IS_LONG;
     167                 :                                                 break;
     168                 :                                 }
     169               7 :                                 STR_FREE(strval);
     170               7 :                                 break;
     171                 :                         }
     172                 :                 case IS_UNICODE:
     173                 :                         {
     174                 :                                 UChar *strval;
     175                 : 
     176          101159 :                                 strval = Z_USTRVAL_P(op);
     177          101159 :                                 switch ((Z_TYPE_P(op)=is_numeric_unicode(strval, Z_USTRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1))) {
     178                 :                                         case IS_DOUBLE:
     179                 :                                         case IS_LONG:
     180          101111 :                                                 break;
     181                 :                                         default:
     182              48 :                                                 Z_LVAL_P(op) = zend_u_strtol(Z_USTRVAL_P(op), NULL, 10);
     183              48 :                                                 Z_TYPE_P(op) = IS_LONG;
     184                 :                                                 break;
     185                 :                                 }
     186          101159 :                                 USTR_FREE(strval);
     187          101159 :                                 break;
     188                 :                         }
     189                 :                         break;
     190                 :                 case IS_BOOL:
     191              39 :                         Z_TYPE_P(op) = IS_LONG;
     192              39 :                         break;
     193                 :                 case IS_RESOURCE:
     194               7 :                         zend_list_delete(Z_LVAL_P(op));
     195               7 :                         Z_TYPE_P(op) = IS_LONG;
     196               7 :                         break;
     197                 :                 case IS_OBJECT:
     198               6 :                         convert_to_long_base(op, 10);
     199               6 :                         break;
     200                 :                 case IS_NULL:
     201              50 :                         ZVAL_LONG(op, 0);
     202                 :                         break;
     203                 :         }
     204                 : 
     205          208102 :         return SUCCESS;
     206                 : }
     207                 : /* }}} */
     208                 : 
     209                 : /* {{{ zendi_convert_scalar_to_number */
     210                 : #define zendi_convert_scalar_to_number(op, holder, result)                      \
     211                 :         if (op==result) {                                                                                               \
     212                 :                 if (Z_TYPE_P(op) != IS_LONG) {                                                          \
     213                 :                         convert_scalar_to_number(op TSRMLS_CC);                                 \
     214                 :                 }                                                                                                                       \
     215                 :         } else {                                                                                                                \
     216                 :                 switch (Z_TYPE_P(op)) {                                                                         \
     217                 :                         case IS_STRING:                                                                                 \
     218                 :                                 {                                                                                                       \
     219                 :                                         switch ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1))) {      \
     220                 :                                                 case IS_DOUBLE:                                                                         \
     221                 :                                                 case IS_LONG:                                                                           \
     222                 :                                                         break;                                                                                  \
     223                 :                                                 default:                                                                                        \
     224                 :                                                         Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);      \
     225                 :                                                         Z_TYPE(holder) = IS_LONG;                                               \
     226                 :                                                         break;                                                                                  \
     227                 :                                         }                                                                                                               \
     228                 :                                         (op) = &(holder);                                                                           \
     229                 :                                         break;                                                                                                  \
     230                 :                                 }                                                                                                                       \
     231                 :                         case IS_UNICODE: \
     232                 :                                 { \
     233                 :                                         switch ((Z_TYPE(holder)=is_numeric_unicode(Z_USTRVAL_P(op), Z_USTRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1))) { \
     234                 :                                                 case IS_DOUBLE: \
     235                 :                                                 case IS_LONG: \
     236                 :                                                         break; \
     237                 :                                                 default: \
     238                 :                                                         Z_LVAL(holder) = zend_u_strtol(Z_USTRVAL_P(op), NULL, 10); \
     239                 :                                                         Z_TYPE(holder) = IS_LONG; \
     240                 :                                                         break; \
     241                 :                                         } \
     242                 :                                         (op) = &(holder);                                                                           \
     243                 :                                         break;                                                                                                  \
     244                 :                                 }                                                                                                                       \
     245                 :                         case IS_BOOL:                                                                                                   \
     246                 :                         case IS_RESOURCE:                                                                                               \
     247                 :                                 ZVAL_LONG(&(holder), Z_LVAL_P(op));                                                 \
     248                 :                                 (op) = &(holder);                                                                                   \
     249                 :                                 break;                                                                                                          \
     250                 :                         case IS_NULL:                                                                                                   \
     251                 :                                 ZVAL_LONG(&(holder), 0);                                                                    \
     252                 :                                 (op) = &(holder);                                                                                   \
     253                 :                                 break;                                                                                                          \
     254                 :                         case IS_OBJECT:                                                                                                 \
     255                 :                                 (holder) = (*(op));                                                                                     \
     256                 :                                 zval_copy_ctor(&(holder));                                                                  \
     257                 :                                 convert_to_long_base(&(holder), 10);                                                \
     258                 :                                 if (Z_TYPE(holder) == IS_LONG) {                                                        \
     259                 :                                         (op) = &(holder);                                                                           \
     260                 :                                 }                                                                                                                       \
     261                 :                                 break;                                                                                                          \
     262                 :                 }                                                                                                                                       \
     263                 :         }
     264                 : 
     265                 : /* }}} */
     266                 : 
     267                 : /* {{{ zendi_convert_to_long */
     268                 : #define zendi_convert_to_long(op, holder, result)                                       \
     269                 :         if (op == result) {                                                                                             \
     270                 :                 convert_to_long(op);                                                                            \
     271                 :         } else if (Z_TYPE_P(op) != IS_LONG) {                                                   \
     272                 :                 switch (Z_TYPE_P(op)) {                                                                         \
     273                 :                         case IS_NULL:                                                                                   \
     274                 :                                 Z_LVAL(holder) = 0;                                                                     \
     275                 :                                 break;                                                                                          \
     276                 :                         case IS_DOUBLE:                                                                                 \
     277                 :                                 Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op));       \
     278                 :                                 break;                                                                                          \
     279                 :                         case IS_STRING:                                                                                 \
     280                 :                                 Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);      \
     281                 :                                 break;                                                                                          \
     282                 :                         case IS_UNICODE:                                                                                \
     283                 :                                 Z_LVAL(holder) = zend_u_strtol(Z_USTRVAL_P(op), NULL, 10);      \
     284                 :                                 break;                                                                                          \
     285                 :                         case IS_ARRAY:                                                                                  \
     286                 :                                 Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);  \
     287                 :                                 break;                                                                                          \
     288                 :                         case IS_OBJECT:                                                                                 \
     289                 :                                 (holder) = (*(op));                                                                     \
     290                 :                                 zval_copy_ctor(&(holder));                                                  \
     291                 :                                 convert_to_long_base(&(holder), 10);                                \
     292                 :                                 break;                                                                                          \
     293                 :                         case IS_BOOL:                                                                                   \
     294                 :                         case IS_RESOURCE:                                                                               \
     295                 :                                 Z_LVAL(holder) = Z_LVAL_P(op);                                          \
     296                 :                                 break;                                                                                          \
     297                 :                         default:                                                                                                \
     298                 :                                 zend_error(E_WARNING, "Cannot convert to ordinal value");     \
     299                 :                                 Z_LVAL(holder) = 0;                                                                     \
     300                 :                                 break;                                                                                          \
     301                 :                 }                                                                                                                       \
     302                 :                 Z_TYPE(holder) = IS_LONG;                                                                       \
     303                 :                 (op) = &(holder);                                                                                   \
     304                 :         }
     305                 : 
     306                 : /* }}} */
     307                 : 
     308                 : /* {{{ zendi_convert_to_boolean */
     309                 : #define zendi_convert_to_boolean(op, holder, result)                            \
     310                 :         if (op==result) {                                                                                               \
     311                 :                 convert_to_boolean(op);                                                                         \
     312                 :         } else if (Z_TYPE_P(op) != IS_BOOL) {                                                   \
     313                 :                 switch (Z_TYPE_P(op)) {                                                                         \
     314                 :                         case IS_NULL:                                                                                   \
     315                 :                                 Z_LVAL(holder) = 0;                                                                     \
     316                 :                                 break;                                                                                          \
     317                 :                         case IS_RESOURCE:                                                                               \
     318                 :                         case IS_LONG:                                                                                   \
     319                 :                                 Z_LVAL(holder) = (Z_LVAL_P(op) ? 1 : 0);                        \
     320                 :                                 break;                                                                                          \
     321                 :                         case IS_DOUBLE:                                                                                 \
     322                 :                                 Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0);                        \
     323                 :                                 break;                                                                                          \
     324                 :                         case IS_STRING:                                                                                 \
     325                 :                                 if (Z_STRLEN_P(op) == 0                                                         \
     326                 :                                         || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {     \
     327                 :                                         Z_LVAL(holder) = 0;                                                             \
     328                 :                                 } else {                                                                                        \
     329                 :                                         Z_LVAL(holder) = 1;                                                             \
     330                 :                                 }                                                                                                       \
     331                 :                                 break;                                                                                          \
     332                 :                         case IS_UNICODE:                                                                                \
     333                 :                                 if (Z_USTRLEN_P(op) == 0                                                        \
     334                 :                                         || (Z_USTRLEN_P(op)==1 &&                                               \
     335                 :                                                 (Z_USTRVAL_P(op)[0]=='0'))) {                           \
     336                 :                                         Z_LVAL(holder) = 0;                                                             \
     337                 :                                 } else {                                                                                        \
     338                 :                                         Z_LVAL(holder) = 1;                                                             \
     339                 :                                 }                                                                                                       \
     340                 :                                 break;                                                                                          \
     341                 :                         case IS_ARRAY:                                                                                  \
     342                 :                                 Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);  \
     343                 :                                 break;                                                                                          \
     344                 :                         case IS_OBJECT:                                                                                 \
     345                 :                                 (holder) = (*(op));                                                                     \
     346                 :                                 zval_copy_ctor(&(holder));                                                  \
     347                 :                                 convert_to_boolean(&(holder));                                              \
     348                 :                                 break;                                                                                          \
     349                 :                         default:                                                                                                \
     350                 :                                 Z_LVAL(holder) = 0;                                                                     \
     351                 :                                 break;                                                                                          \
     352                 :                 }                                                                                                                       \
     353                 :                 Z_TYPE(holder) = IS_BOOL;                                                                       \
     354                 :                 (op) = &(holder);                                                                                   \
     355                 :         }
     356                 : 
     357                 : /* }}} */
     358                 : 
     359                 : /* {{{ convert_object_to_type */
     360                 : #define convert_object_to_type(op, ctype, conv_func)                                                                            \
     361                 :         if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                           \
     362                 :                 zval dst;                                                                                                                                                       \
     363                 :                 if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype, NULL TSRMLS_CC) == FAILURE) {           \
     364                 :                         zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
     365                 :                                 "Object of class %v could not be converted to %s", Z_OBJCE_P(op)->name,            \
     366                 :                         zend_get_type_by_const(ctype));                                                                                                 \
     367                 :                 } else {                                                                                                                                                        \
     368                 :                         zval_dtor(op);                                                                                                                                  \
     369                 :                         Z_TYPE_P(op) = ctype;                                                                                                                   \
     370                 :                         op->value = dst.value;                                                                                                                       \
     371                 :                         retval = SUCCESS;                                                                                                                               \
     372                 :                 }                                                                                                                                                                       \
     373                 :         } else {                                                                                                                                                                \
     374                 :                 if (Z_OBJ_HT_P(op)->get) {                                                                                                                   \
     375                 :                         zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);                                                             \
     376                 :                         if (Z_TYPE_P(newop) != IS_OBJECT) {                                                                                             \
     377                 :                                 /* for safety - avoid loop */                                                                                           \
     378                 :                                 zval_dtor(op);                                                                                                                          \
     379                 :                                 *op = *newop;                                                                                                                           \
     380                 :                                 FREE_ZVAL(newop);                                                                                                                       \
     381                 :                                 retval = conv_func(op);                                                                                                         \
     382                 :                         }                                                                                                                                                               \
     383                 :                 }                                                                                                                                                                       \
     384                 :         }
     385                 : 
     386                 : /* }}} */
     387                 : 
     388                 : ZEND_API int convert_to_long(zval *op) /* {{{ */
     389          975593 : {
     390          975593 :         return convert_to_long_base(op, 10);
     391                 : }
     392                 : /* }}} */
     393                 : 
     394                 : ZEND_API int convert_to_long_base(zval *op, int base) /* {{{ */
     395          979421 : {
     396                 :         long tmp;
     397                 : 
     398          979421 :         switch (Z_TYPE_P(op)) {
     399                 :                 case IS_NULL:
     400            1125 :                         Z_LVAL_P(op) = 0;
     401            1125 :                         break;
     402                 :                 case IS_RESOURCE: {
     403                 :                                 TSRMLS_FETCH();
     404                 : 
     405             116 :                                 zend_list_delete(Z_LVAL_P(op));
     406                 :                         }
     407                 :                         /* break missing intentionally */
     408                 :                 case IS_BOOL:
     409                 :                 case IS_LONG:
     410          930795 :                         break;
     411                 :                 case IS_DOUBLE:
     412            9097 :                         Z_LVAL_P(op) = zend_dval_to_lval(Z_DVAL_P(op));
     413            9097 :                         break;
     414                 :                 case IS_STRING:
     415                 :                         {
     416           33898 :                                 char *strval = Z_STRVAL_P(op);
     417                 : 
     418           33898 :                                 Z_LVAL_P(op) = strtol(strval, NULL, base);
     419           33898 :                                 STR_FREE(strval);
     420                 :                         }
     421           33898 :                         break;
     422                 :                 case IS_UNICODE:
     423                 :                         {
     424            3590 :                                 UChar *strval = Z_USTRVAL_P(op);
     425            3590 :                                 Z_LVAL_P(op) = zend_u_strtol(strval, NULL, base);
     426            3590 :                                 USTR_FREE(strval);
     427                 :                         }
     428            3590 :                         break;
     429                 :                 case IS_ARRAY:
     430             863 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     431             863 :                         zval_dtor(op);
     432             863 :                         Z_LVAL_P(op) = tmp;
     433             863 :                         break;
     434                 :                 case IS_OBJECT:
     435                 :                         {
     436              53 :                                 int retval = 1;
     437                 :                                 TSRMLS_FETCH();
     438                 : 
     439              53 :                                 convert_object_to_type(op, IS_LONG, convert_to_long);
     440                 : 
     441              53 :                                 if (Z_TYPE_P(op) == IS_LONG) {
     442              53 :                                         return SUCCESS;
     443                 :                                 }
     444                 : 
     445               0 :                                 zend_error(E_NOTICE, "Object of class %v could not be converted to int", Z_OBJCE_P(op)->name);
     446                 : 
     447               0 :                                 zval_dtor(op);
     448               0 :                                 ZVAL_LONG(op, retval);
     449               0 :                                 return FAILURE;
     450                 :                         }
     451                 :                 default:
     452               0 :                         zend_error(E_WARNING, "Cannot convert to ordinal value");
     453               0 :                         zval_dtor(op);
     454               0 :                         Z_LVAL_P(op) = 0;
     455               0 :                         return FAILURE;
     456                 :         }
     457                 : 
     458          979368 :         Z_TYPE_P(op) = IS_LONG;
     459          979368 :         return SUCCESS;
     460                 : }
     461                 : /* }}} */
     462                 : 
     463                 : ZEND_API int convert_to_double(zval *op) /* {{{ */
     464          332312 : {
     465                 :         double tmp;
     466                 : 
     467          332312 :         switch (Z_TYPE_P(op)) {
     468                 :                 case IS_NULL:
     469             319 :                         Z_DVAL_P(op) = 0.0;
     470             319 :                         break;
     471                 :                 case IS_RESOURCE: {
     472                 :                                 TSRMLS_FETCH();
     473                 : 
     474              48 :                                 zend_list_delete(Z_LVAL_P(op));
     475                 :                         }
     476                 :                         /* break missing intentionally */
     477                 :                 case IS_BOOL:
     478                 :                 case IS_LONG:
     479          258289 :                         Z_DVAL_P(op) = (double) Z_LVAL_P(op);
     480          258289 :                         break;
     481                 :                 case IS_DOUBLE:
     482           72547 :                         break;
     483                 :                 case IS_STRING:
     484                 :                         {
     485              26 :                                 char *strval = Z_STRVAL_P(op);
     486                 : 
     487              26 :                                 Z_DVAL_P(op) = zend_strtod(strval, NULL);
     488              26 :                                 STR_FREE(strval);
     489                 :                         }
     490              26 :                         break;
     491                 :                 case IS_UNICODE:
     492                 :                         {
     493             742 :                                 UChar *strval = Z_USTRVAL_P(op);
     494                 : 
     495             742 :                                 Z_DVAL_P(op) = zend_u_strtod(strval, NULL);
     496             742 :                                 USTR_FREE(strval);
     497                 :                         }
     498             742 :                         break;
     499                 :                 case IS_ARRAY:
     500             369 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     501             369 :                         zval_dtor(op);
     502             369 :                         Z_DVAL_P(op) = tmp;
     503             369 :                         break;
     504                 :                 case IS_OBJECT:
     505                 :                         {
     506              20 :                                 double retval = 1.0;
     507                 :                                 TSRMLS_FETCH();
     508                 : 
     509              20 :                                 convert_object_to_type(op, IS_DOUBLE, convert_to_double);
     510                 : 
     511              20 :                                 if (Z_TYPE_P(op) == IS_DOUBLE) {
     512              20 :                                         return SUCCESS;
     513                 :                                 }
     514                 : 
     515               0 :                                 zend_error(E_NOTICE, "Object of class %v could not be converted to double", Z_OBJCE_P(op)->name);
     516                 : 
     517               0 :                                 zval_dtor(op);
     518               0 :                                 ZVAL_DOUBLE(op, retval);
     519               0 :                                 return FAILURE;
     520                 :                         }
     521                 :                 default:
     522               0 :                         zend_error(E_WARNING, "Cannot convert to real value (type=%d)", Z_TYPE_P(op));
     523               0 :                         zval_dtor(op);
     524               0 :                         Z_DVAL_P(op) = 0;
     525               0 :                         return FAILURE;
     526                 :         }
     527                 : 
     528          332292 :         Z_TYPE_P(op) = IS_DOUBLE;
     529          332292 :         return SUCCESS;
     530                 : }
     531                 : /* }}} */
     532                 : 
     533                 : ZEND_API int convert_to_null(zval *op) /* {{{ */
     534            1106 : {
     535            1106 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     536               6 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     537                 :                         zval *org;
     538                 :                         TSRMLS_FETCH();
     539                 : 
     540               6 :                         ALLOC_ZVAL(org);
     541               6 :                         *org = *op;
     542               6 :                         if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL, NULL TSRMLS_CC) == SUCCESS) {
     543               0 :                                 zval_dtor(org);
     544               0 :                                 return SUCCESS;
     545                 :                         }
     546               6 :                         *op = *org;
     547               6 :                         FREE_ZVAL(org);
     548                 :                 }
     549                 :         }
     550                 : 
     551            1106 :         zval_dtor(op);
     552            1106 :         Z_TYPE_P(op) = IS_NULL;
     553            1106 :         return SUCCESS;
     554                 : }
     555                 : /* }}} */
     556                 : 
     557                 : ZEND_API int convert_to_boolean(zval *op) /* {{{ */
     558           80535 : {
     559                 :         int tmp;
     560                 : 
     561           80535 :         switch (Z_TYPE_P(op)) {
     562                 :                 case IS_BOOL:
     563            3478 :                         break;
     564                 :                 case IS_NULL:
     565             101 :                         Z_LVAL_P(op) = 0;
     566             101 :                         break;
     567                 :                 case IS_RESOURCE: {
     568                 :                                 TSRMLS_FETCH();
     569                 : 
     570               8 :                                 zend_list_delete(Z_LVAL_P(op));
     571                 :                         }
     572                 :                         /* break missing intentionally */
     573                 :                 case IS_LONG:
     574             533 :                         Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0);
     575             533 :                         break;
     576                 :                 case IS_DOUBLE:
     577             161 :                         Z_LVAL_P(op) = (Z_DVAL_P(op) ? 1 : 0);
     578             161 :                         break;
     579                 :                 case IS_STRING:
     580                 :                         {
     581              36 :                                 char *strval = Z_STRVAL_P(op);
     582                 : 
     583              40 :                                 if (Z_STRLEN_P(op) == 0
     584                 :                                         || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
     585               4 :                                         Z_LVAL_P(op) = 0;
     586                 :                                 } else {
     587              32 :                                         Z_LVAL_P(op) = 1;
     588                 :                                 }
     589              36 :                                 STR_FREE(strval);
     590                 :                         }
     591              36 :                         break;
     592                 :                 case IS_UNICODE:
     593                 :                         {
     594             213 :                                 UChar *strval = Z_USTRVAL_P(op);
     595                 : 
     596             270 :                                 if (Z_USTRLEN_P(op) == 0
     597                 :                                         || (Z_USTRLEN_P(op)==1 && Z_USTRVAL_P(op)[0]=='0')) {
     598              57 :                                         Z_LVAL_P(op) = 0;
     599                 :                                 } else {
     600             156 :                                         Z_LVAL_P(op) = 1;
     601                 :                                 }
     602             213 :                                 USTR_FREE(strval);
     603                 :                         }
     604             213 :                         break;
     605                 :                 case IS_ARRAY:
     606              20 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     607              20 :                         zval_dtor(op);
     608              20 :                         Z_LVAL_P(op) = tmp;
     609              20 :                         break;
     610                 :                 case IS_OBJECT:
     611                 :                         {
     612           75993 :                                 zend_bool retval = 1;
     613                 :                                 TSRMLS_FETCH();
     614                 : 
     615           75993 :                                 convert_object_to_type(op, IS_BOOL, convert_to_boolean);
     616                 : 
     617           75993 :                                 if (Z_TYPE_P(op) == IS_BOOL) {
     618           75993 :                                         return SUCCESS;
     619                 :                                 }
     620                 : 
     621               0 :                                 zval_dtor(op);
     622               0 :                                 ZVAL_BOOL(op, retval);
     623               0 :                                 return FAILURE;
     624                 :                         }
     625                 :                 default:
     626               0 :                         zval_dtor(op);
     627               0 :                         Z_LVAL_P(op) = 0;
     628                 :                         break;
     629                 :         }
     630                 : 
     631            4542 :         Z_TYPE_P(op) = IS_BOOL;
     632            4542 :         return SUCCESS;
     633                 : }
     634                 : /* }}} */
     635                 : 
     636                 : #define NUM_BUF_SIZE 512
     637                 : 
     638                 : /* rewrite of ap_php_conv_10 for UChar support */
     639                 : static UChar* zend_u_format_long(long lnum, UChar *result_end, int *result_len) /* {{{ */
     640         1557757 : {
     641         1557757 :         UChar *p = result_end;
     642                 :         unsigned long magnitude;
     643                 : 
     644         1557757 :         *--p = 0;
     645                 : 
     646         1557757 :         if (lnum < 0) {
     647            2015 :                 long t = lnum + 1;
     648            2015 :                 magnitude = ((unsigned long) - t) + 1;
     649                 :         } else {
     650         1555742 :                 magnitude = (unsigned long) lnum;
     651                 :         }
     652                 : 
     653                 :         do {
     654         3931586 :                 unsigned long new_magnitude = magnitude / 10;
     655                 : 
     656         3931586 :                 *--p = (UChar)(magnitude - new_magnitude * 10 + 0x30 /*'0'*/);
     657         3931586 :                 magnitude = new_magnitude;
     658                 :         }
     659         3931586 :         while (magnitude);
     660                 : 
     661         1557757 :         if (lnum < 0) {
     662            2015 :                 *--p = (UChar) 0x2d /*'-'*/;
     663                 :         }
     664                 : 
     665         1557757 :         *result_len = result_end - p - 1;
     666         1557757 :         return p;
     667                 : }
     668                 : /* }}} */
     669                 : 
     670                 : #define NDIG 320
     671                 : 
     672                 : /* rewrite of ap_php_cvt for UChar support */
     673                 : static UChar* zend_u_format_double(double arg, int ndigits, int *decpt, int *sign, int eflag, UChar *buf) /* {{{ */
     674           15490 : {
     675                 :         register int r2;
     676                 :         int mvl;
     677                 :         double fi, fj;
     678                 :         register UChar *p, *p1;
     679                 : 
     680           15490 :         if (ndigits >= NDIG - 1)
     681               0 :                 ndigits = NDIG - 2;
     682           15490 :         r2 = 0;
     683           15490 :         *sign = 0;
     684           15490 :         p = &buf[0];
     685           15490 :         if (arg < 0) {
     686             729 :                 *sign = 1;
     687             729 :                 arg = -arg;
     688                 :         }
     689           15490 :         arg = modf(arg, &fi);
     690           15490 :         p1 = &buf[NDIG];
     691                 :         /*
     692                 :          * Do integer part
     693                 :          */
     694           15490 :         if (fi != 0) {
     695           54613 :                 while (fi != 0) {
     696           28667 :                         fj = modf(fi / 10, &fi);
     697           28667 :                         if (p1 <= &buf[0]) {
     698               0 :                                 mvl = NDIG - ndigits;
     699               0 :                                 if (ndigits > 0) {
     700               0 :                                         memmove(&buf[mvl], &buf[0], (NDIG-mvl-1) * sizeof(UChar));
     701                 :                                 }
     702               0 :                                 p1 += mvl;
     703                 :                         }
     704           28667 :                         *--p1 = (UChar) ((fj + .03) * 10) + 0x30 /*'0'*/;
     705           28667 :                         r2++;
     706                 :                 }
     707           54613 :                 while (p1 < &buf[NDIG]) {
     708           28667 :                         *p++ = *p1++;
     709                 :                 }
     710            2517 :         } else if (arg > 0) {
     711            8265 :                 while ((fj = arg * 10) < 1) {
     712            3363 :                         if (!eflag && (r2 * -1) < ndigits) {
     713               0 :                                 break;
     714                 :                         }
     715            3363 :                         arg = fj;
     716            3363 :                         r2--;
     717                 :                 }
     718                 :         }
     719           15490 :         p1 = &buf[ndigits];
     720           15490 :         if (eflag == 0)
     721               0 :                 p1 += r2;
     722           15490 :         *decpt = r2;
     723           15490 :         if (p1 < &buf[0]) {
     724               0 :                 buf[0] = 0;
     725               0 :                 return (buf);
     726                 :         }
     727           15490 :         if (p <= p1 && p < &buf[NDIG]) {
     728           15456 :                 arg = modf(arg * 10, &fj);
     729           15456 :                 if ((int)fj==10) {
     730               0 :                         *p++ = (UChar) 0x31 /*'1'*/;
     731               0 :                         fj = 0;
     732               0 :                         *decpt = ++r2;
     733                 :                 }
     734          235182 :                 while (p <= p1 && p < &buf[NDIG]) {
     735          204270 :                         *p++ = (UChar) fj + 0x30 /*'0'*/;
     736          204270 :                         arg = modf(arg * 10, &fj);
     737                 :                 }
     738                 :         }
     739           15490 :         if (p1 >= &buf[NDIG]) {
     740               0 :                 buf[NDIG - 1] = 0;
     741               0 :                 return (buf);
     742                 :         }
     743           15490 :         p = p1;
     744           15490 :         *p1 += 5;
     745           46271 :         while (*p1 > (UChar) 0x39 /*'9'*/) {
     746           15291 :                 *p1 = (UChar) 0x30 /*'0'*/;
     747           15291 :                 if (p1 > buf)
     748           15286 :                         ++ * --p1;
     749                 :                 else {
     750               5 :                         *p1 = (UChar) 0x31 /*'1'*/;
     751               5 :                         (*decpt)++;
     752               5 :                         if (eflag == 0) {
     753               0 :                                 if (p > buf)
     754               0 :                                         *p = (UChar) 0x30 /*'0'*/;
     755               0 :                                 p++;
     756                 :                         }
     757                 :                 }
     758                 :         }
     759           15490 :         *p = 0;
     760           15490 :         return (buf);
     761                 : }
     762                 : /* }}} */
     763                 : 
     764                 : /* rewrite of ap_php_gcvt for UChar support */
     765                 : static UChar* zend_u_format_gdouble(double dnum, int ndigit, UChar *result) /* {{{ */
     766           18497 : {
     767                 :         int sign, decpt;
     768                 :         register UChar *p1, *p2;
     769                 :         register int i;
     770                 :         UChar buf1[NDIG];
     771                 :         static zend_bool did_string_init = FALSE;
     772                 :         U_STRING_DECL(u_nan, "NAN", 3);
     773                 :         U_STRING_DECL(u_inf, "INF", 3);
     774                 :         U_STRING_DECL(u_ninf, "-INF", 4);
     775                 : 
     776           18497 :         if (!did_string_init) {
     777             321 :                 U_STRING_INIT(u_nan, "NAN", 3);
     778             321 :                 U_STRING_INIT(u_inf, "INF", 3);
     779             321 :                 U_STRING_INIT(u_ninf, "-INF", 4);
     780             321 :                 did_string_init = TRUE;
     781                 :         }
     782                 : 
     783                 :         /* check for out-of-bounds numbers */
     784           18497 :         if (zend_isnan(dnum)) {
     785            1498 :                 u_memcpy(result, u_nan, 3);
     786            1498 :                 result[3] = 0;
     787            1498 :                 return result;
     788           16999 :         } else if (zend_isinf(dnum)) {
     789            1509 :                 if (dnum > 0) {
     790            1509 :                         u_memcpy(result, u_inf, 3);
     791            1509 :                         result[3] = 0;
     792                 :                 } else {
     793               0 :                         u_memcpy(result, u_ninf, 3);
     794               0 :                         result[4] = 0;
     795                 :                 }
     796            1509 :                 return result;
     797                 :         }
     798                 : 
     799           15490 :         if (ndigit >= NDIG - 1) {
     800               0 :                 ndigit = NDIG - 2;
     801                 :         }
     802                 : 
     803           15490 :         p1 = zend_u_format_double(dnum, ndigit, &decpt, &sign, 1, buf1);
     804           15490 :         p2 = result;
     805                 : 
     806           15490 :         if (sign) {
     807             729 :                 *p2++ = (UChar) 0x2d /*'-'*/;
     808                 :         }
     809                 :         /* if decimal point position is less than precision, cut zeros only in fractional part */
     810           15490 :         if (decpt <= ndigit) {
     811           15456 :                 i = ndigit - 1;
     812           80056 :                 while (i > 0 && i >= decpt && p1[i] == (UChar) 0x30 /*'0'*/) {
     813           49144 :                         ndigit--;
     814           49144 :                         i--;
     815                 :                 }
     816                 :         } else {
     817                 :         /* otherwise cut all trailing zeros */
     818             212 :                 for (i = ndigit - 1; i > 0 && p1[i] == (UChar) 0x30 /*'0'*/; i--) {
     819             178 :                         ndigit--;
     820                 :                 }
     821                 :         }
     822                 : 
     823           15747 :         if ((decpt >= 0 && decpt - ndigit > 4)
     824                 :                 || (decpt < 0 && decpt < -3)) {           /* use E-style */
     825             257 :                 decpt--;
     826             257 :                 *p2++ = *p1++;
     827             257 :                 *p2++ = (UChar) 0x2e /*'.'*/;
     828            1912 :                 for (i = 1; i < ndigit; i++)
     829            1655 :                         *p2++ = *p1++;
     830             257 :                 if (*(p2 - 1) == (UChar) 0x2e /*'.'*/) {
     831              31 :                         *p2++ = (UChar) 0x30 /*'0'*/;
     832                 :                 }
     833             257 :                 *p2++ = (UChar) 0x45 /*'E'*/;
     834             257 :                 if (decpt < 0) {
     835             223 :                         decpt = -decpt;
     836             223 :                         *p2++ = (UChar) 0x2d /*'-'*/;
     837                 :                 } else
     838              34 :                         *p2++ = (UChar) 0x2b /*'+'*/;
     839             257 :                 if (decpt / 100 > 0)
     840               5 :                         *p2++ = (UChar) (decpt / 100 + 0x30 /*'0'*/);
     841             257 :                 if (decpt / 10 > 0)
     842              51 :                         *p2++ = (UChar) ((decpt % 100) / 10 + 0x30 /*'0'*/);
     843             257 :                 *p2++ = (UChar) (decpt % 10 + 0x30 /*'0'*/);
     844                 :         } else {
     845           15233 :                 if (decpt <= 0) {
     846            2294 :                         if (*p1 != (UChar) 0x30 /*'0'*/) {
     847            2228 :                                 *p2++ = (UChar) 0x30 /*'0'*/;
     848            2228 :                                 *p2++ = (UChar) 0x2e /*'.'*/;
     849                 :                         }
     850            4666 :                         while (decpt < 0) {
     851              78 :                                 decpt++;
     852              78 :                                 *p2++ = (UChar) 0x30 /*'0'*/;
     853                 :                         }
     854                 :                 }
     855          180771 :                 for (i = 1; i <= ndigit; i++) {
     856          165538 :                         *p2++ = *p1++;
     857          165538 :                         if (i == decpt)
     858           12939 :                                 *p2++ = (UChar) 0x2e /*'.'*/;
     859                 :                 }
     860           15233 :                 if (ndigit < decpt) {
     861               0 :                         while (ndigit++ < decpt)
     862               0 :                                 *p2++ = (UChar) 0x30 /*'0'*/;
     863               0 :                         *p2++ = (UChar) 0x2e /*'.'*/;
     864                 :                 }
     865                 :         }
     866           15490 :         if (p2[-1] == (UChar) 0x2e /*'.'*/)
     867            1406 :                 p2--;
     868           15490 :         *p2 = 0;
     869           15490 :         return (result);
     870                 : }
     871                 : /* }}} */
     872                 : 
     873                 : ZEND_API int _convert_to_unicode(zval *op TSRMLS_DC ZEND_FILE_LINE_DC) /* {{{ */
     874         2217598 : {
     875         2217598 :         return _convert_to_unicode_with_converter(op, ZEND_U_CONVERTER(UG(runtime_encoding_conv)) TSRMLS_CC ZEND_FILE_LINE_CC);
     876                 : }
     877                 : /* }}} */
     878                 : 
     879                 : ZEND_API int _convert_to_unicode_with_converter(zval *op, UConverter *conv TSRMLS_DC ZEND_FILE_LINE_DC) /* {{{ */
     880         2419107 : {
     881         2419107 :         switch (Z_TYPE_P(op)) {
     882                 :                 case IS_NULL:
     883            2781 :                         Z_USTRVAL_P(op) = USTR_MAKE_REL("");
     884            2781 :                         Z_USTRLEN_P(op) = 0;
     885            2781 :                         break;
     886                 :                 case IS_UNICODE:
     887          528416 :                         break;
     888                 :                 case IS_STRING:
     889          301258 :                         return zval_string_to_unicode_ex(op, conv TSRMLS_CC);
     890                 :                 case IS_BOOL:
     891            9269 :                         if (Z_LVAL_P(op)) {
     892            1415 :                                 Z_USTRVAL_P(op) = USTR_MAKE_REL("1");
     893            1415 :                                 Z_USTRLEN_P(op) = 1;
     894                 :                         } else {
     895            7854 :                                 Z_USTRVAL_P(op) = USTR_MAKE_REL("");
     896            7854 :                                 Z_USTRLEN_P(op) = 0;
     897                 :                         }
     898            9269 :                         break;
     899                 :                 case IS_RESOURCE: {
     900                 :                         UChar num_buf[NUM_BUF_SIZE], *result;
     901                 :                         int result_len, rstr_len;
     902            5049 :                         long rval = Z_LVAL_P(op);
     903                 : 
     904            5049 :                         zend_list_delete(Z_LVAL_P(op));
     905            5049 :                         result = zend_u_format_long(rval, &num_buf[NUM_BUF_SIZE], &result_len);
     906                 : 
     907            5049 :                         rstr_len = sizeof("Resource id #")-1;
     908            5049 :                         Z_USTRLEN_P(op) = rstr_len + result_len;
     909            5049 :                         Z_USTRVAL_P(op) = eumalloc_rel(Z_USTRLEN_P(op) + 1);
     910            5049 :                         u_charsToUChars("Resource id #", Z_USTRVAL_P(op), rstr_len);
     911                 :                         /* result_len+1 takes care of terminating NULL */
     912            5049 :                         u_memcpy(Z_USTRVAL_P(op) + rstr_len, result, result_len+1);
     913            5049 :                         break;
     914                 :                 }
     915                 :                 case IS_LONG: {
     916                 :                         UChar num_buf[NUM_BUF_SIZE], *result;
     917                 :                         int result_len;
     918         1552708 :                         long lval = Z_LVAL_P(op);
     919                 : 
     920         1552708 :                         result = zend_u_format_long(lval, &num_buf[NUM_BUF_SIZE], &result_len);
     921                 : 
     922         1552708 :                         Z_USTRVAL_P(op) = eustrndup(result, result_len);
     923         1552708 :                         Z_USTRLEN_P(op) = result_len;
     924         1552708 :                         break;
     925                 :                 }
     926                 :                 case IS_DOUBLE: {
     927                 :                         UChar num_buf[NUM_BUF_SIZE], *result;
     928           18497 :                         double dval = Z_DVAL_P(op);
     929                 : 
     930           18497 :                         result = zend_u_format_gdouble(dval, (int) EG(precision), &num_buf[1]);
     931           18497 :                         if (*result == (UChar) 0x2b /*'+'*/) {
     932               0 :                                 result++;
     933                 :                         }
     934           18497 :                         Z_USTRLEN_P(op) = u_strlen(result);
     935           18497 :                         Z_USTRVAL_P(op) = eustrndup(result, Z_USTRLEN_P(op));
     936           18497 :                         break;
     937                 :                 }
     938                 :                 case IS_ARRAY:
     939            1060 :                         zend_error(E_NOTICE, "Array to string conversion");
     940            1060 :                         zval_dtor(op);
     941            1060 :                         Z_USTRVAL_P(op) = USTR_MAKE_REL("Array");
     942            1060 :                         Z_USTRLEN_P(op) = sizeof("Array")-1;
     943            1060 :                         Z_TYPE_P(op) = IS_UNICODE;
     944            1060 :                         return FAILURE;
     945                 :                 case IS_OBJECT: {
     946              69 :                         int retval = FAILURE;
     947                 : 
     948              69 :                         convert_object_to_type(op, IS_UNICODE, convert_to_unicode);
     949                 : 
     950              68 :                         if (retval == SUCCESS && Z_TYPE_P(op) == IS_UNICODE) {
     951              64 :                                 return SUCCESS;
     952                 :                         }
     953                 : 
     954               4 :                         zend_error(E_NOTICE, "Object of class %v to string conversion", Z_OBJCE_P(op)->name);
     955               4 :                         zval_dtor(op);
     956               4 :                         Z_USTRVAL_P(op) = USTR_MAKE_REL("Object");
     957               4 :                         Z_USTRLEN_P(op) = sizeof("Object")-1;
     958               4 :                         Z_TYPE_P(op) = IS_UNICODE;
     959               4 :                         return FAILURE;
     960                 :                 }
     961                 :                 default:
     962               0 :                         zval_dtor(op);
     963               0 :                         ZVAL_BOOL(op, 0);
     964               0 :                         return FAILURE;
     965                 :         }
     966                 : 
     967         2116720 :         Z_TYPE_P(op) = IS_UNICODE;
     968         2116720 :         return SUCCESS;
     969                 : }
     970                 : /* }}} */
     971                 : 
     972                 : ZEND_API int _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     973         4410326 : {
     974                 :         TSRMLS_FETCH();
     975         4410326 :         return _convert_to_string_with_converter(op, ZEND_U_CONVERTER(UG(runtime_encoding_conv)) TSRMLS_CC ZEND_FILE_LINE_CC);
     976                 : }
     977                 : /* }}} */
     978                 : 
     979                 : ZEND_API int _convert_to_string_with_converter(zval *op, UConverter *conv TSRMLS_DC ZEND_FILE_LINE_DC) /* {{{ */
     980         4941355 : {
     981                 :         long lval;
     982                 :         double dval;
     983                 : 
     984         4941355 :         switch (Z_TYPE_P(op)) {
     985                 :                 case IS_NULL:
     986            3328 :                         Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
     987            3328 :                         Z_STRLEN_P(op) = 0;
     988            3328 :                         break;
     989                 :                 case IS_STRING:
     990          178608 :                         break;
     991                 :                 case IS_UNICODE:
     992         3570411 :                         return zval_unicode_to_string_ex(op, conv TSRMLS_CC);
     993                 :                 case IS_BOOL:
     994             898 :                         if (Z_LVAL_P(op)) {
     995             349 :                                 Z_STRVAL_P(op) = estrndup_rel("1", 1);
     996             349 :                                 Z_STRLEN_P(op) = 1;
     997                 :                         } else {
     998             549 :                                 Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
     999             549 :                                 Z_STRLEN_P(op) = 0;
    1000                 :                         }
    1001             898 :                         break;
    1002                 :                 case IS_RESOURCE: {
    1003              15 :                         long tmp = Z_LVAL_P(op);
    1004                 : 
    1005              15 :                         zend_list_delete(Z_LVAL_P(op));
    1006              15 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "Resource id #%ld", tmp);
    1007              15 :                         break;
    1008                 :                 }
    1009                 :                 case IS_LONG:
    1010         1187158 :                         lval = Z_LVAL_P(op);
    1011                 : 
    1012         1187158 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%ld", lval);
    1013         1187158 :                         break;
    1014                 :                 case IS_DOUBLE: {
    1015             810 :                         dval = Z_DVAL_P(op);
    1016             810 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), dval);
    1017                 :                         /* %G already handles removing trailing zeros from the fractional part, yay */
    1018             810 :                         break;
    1019                 :                 }
    1020                 :                 case IS_ARRAY:
    1021              90 :                         zend_error(E_NOTICE, "Array to string conversion");
    1022              90 :                         zval_dtor(op);
    1023              90 :                         Z_STRVAL_P(op) = estrndup_rel("Array", sizeof("Array")-1);
    1024              90 :                         Z_STRLEN_P(op) = sizeof("Array")-1;
    1025              90 :                         Z_TYPE_P(op) = IS_STRING;
    1026              90 :                         return FAILURE;
    1027                 :                 case IS_OBJECT: {
    1028              37 :                         int retval = FAILURE;
    1029                 : 
    1030              37 :                         convert_object_to_type(op, IS_STRING, convert_to_string);
    1031                 : 
    1032              30 :                         if (retval == SUCCESS && Z_TYPE_P(op) == IS_STRING) {
    1033              18 :                                 return SUCCESS;
    1034                 :                         }
    1035                 : 
    1036              12 :                         zend_error(E_NOTICE, "Object of class %v to string conversion", Z_OBJCE_P(op)->name);
    1037              12 :                         zval_dtor(op);
    1038              12 :                         Z_STRVAL_P(op) = estrndup_rel("Object", sizeof("Object")-1);
    1039              12 :                         Z_STRLEN_P(op) = sizeof("Object")-1;
    1040              12 :                         Z_TYPE_P(op) = IS_STRING;
    1041              12 :                         return FAILURE;
    1042                 :                 }
    1043                 :                 default:
    1044               0 :                         zval_dtor(op);
    1045               0 :                         ZVAL_BOOL(op, 0);
    1046               0 :                         return FAILURE;
    1047                 :         }
    1048                 : 
    1049         1370817 :         Z_TYPE_P(op) = IS_STRING;
    1050         1370817 :         return SUCCESS;
    1051                 : }
    1052                 : /* }}} */
    1053                 : 
    1054                 : static int convert_scalar_to_array(zval *op, int type TSRMLS_DC) /* {{{ */
    1055             348 : {
    1056                 :         zval *entry;
    1057                 : 
    1058             348 :         ALLOC_ZVAL(entry);
    1059             348 :         *entry = *op;
    1060             348 :         INIT_PZVAL(entry);
    1061                 : 
    1062             348 :         switch (type) {
    1063                 :                 case IS_ARRAY:
    1064             224 :                         ALLOC_HASHTABLE(Z_ARRVAL_P(op));
    1065             224 :                         zend_u_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0, 0);
    1066             224 :                         zend_hash_index_update(Z_ARRVAL_P(op), 0, (void *) &entry, sizeof(zval *), NULL);
    1067             224 :                         Z_TYPE_P(op) = IS_ARRAY;
    1068             224 :                         break;
    1069                 :                 case IS_OBJECT:
    1070             124 :                         object_init(op);
    1071             124 :                         zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
    1072                 :                         break;
    1073                 :         }
    1074                 : 
    1075             348 :         return SUCCESS;
    1076                 : }
    1077                 : /* }}} */
    1078                 : 
    1079                 : ZEND_API int convert_to_array(zval *op) /* {{{ */
    1080           17219 : {
    1081                 :         TSRMLS_FETCH();
    1082                 : 
    1083           17219 :         switch (Z_TYPE_P(op)) {
    1084                 :                 case IS_ARRAY:
    1085           16955 :                         break;
    1086                 : /* OBJECTS_OPTIMIZE */
    1087                 :                 case IS_OBJECT:
    1088                 :                         {
    1089                 :                                 zval *tmp;
    1090                 :                                 HashTable *ht;
    1091              15 :                                 int retval = FAILURE;
    1092                 : 
    1093              15 :                                 ALLOC_HASHTABLE(ht);
    1094              15 :                                 zend_u_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0, 0);
    1095              15 :                                 if (Z_OBJ_HT_P(op)->get_properties) {
    1096              15 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
    1097              15 :                                         if (obj_ht) {
    1098              15 :                                                 zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
    1099              15 :                                                 retval = SUCCESS;
    1100                 :                                         }
    1101                 :                                 } else {
    1102               0 :                                         convert_object_to_type(op, IS_ARRAY, convert_to_array);
    1103                 : 
    1104               0 :                                         if (Z_TYPE_P(op) == IS_ARRAY) {
    1105               0 :                                                 zend_hash_destroy(ht);
    1106               0 :                                                 FREE_HASHTABLE(ht);
    1107               0 :                                                 return SUCCESS;
    1108                 :                                         }
    1109                 :                                 }
    1110              15 :                                 zval_dtor(op);
    1111              15 :                                 Z_TYPE_P(op) = IS_ARRAY;
    1112              15 :                                 Z_ARRVAL_P(op) = ht;
    1113              15 :                                 return retval;
    1114                 :                         }
    1115                 :                         break;
    1116                 :                 case IS_NULL:
    1117              25 :                         ALLOC_HASHTABLE(Z_ARRVAL_P(op));
    1118              25 :                         zend_u_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0, 0);
    1119              25 :                         Z_TYPE_P(op) = IS_ARRAY;
    1120              25 :                         break;
    1121                 :                 default:
    1122             224 :                         return convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
    1123                 :         }
    1124                 : 
    1125           16980 :         return SUCCESS;
    1126                 : }
    1127                 : /* }}} */
    1128                 : 
    1129                 : ZEND_API int convert_to_object(zval *op) /* {{{ */
    1130             208 : {
    1131                 :         TSRMLS_FETCH();
    1132                 : 
    1133             208 :         switch (Z_TYPE_P(op)) {
    1134                 :                 case IS_ARRAY:
    1135                 :                         {
    1136              67 :                                 object_and_properties_init(op, zend_standard_class_def, Z_ARRVAL_P(op));
    1137              67 :                                 break;
    1138                 :                         }
    1139                 :                 case IS_OBJECT:
    1140              10 :                         break;
    1141                 :                 case IS_NULL:
    1142               7 :                         object_init(op);
    1143               7 :                         break;
    1144                 :                 default:
    1145             124 :                         return convert_scalar_to_array(op, IS_OBJECT TSRMLS_CC);
    1146                 :         }
    1147                 : 
    1148              84 :         return SUCCESS;
    1149                 : }
    1150                 : /* }}} */
    1151                 : 
    1152                 : ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
    1153               0 : {
    1154                 :         zval **arg;
    1155                 :         va_list ap;
    1156                 : 
    1157               0 :         va_start(ap, argc);
    1158                 : 
    1159               0 :         while (argc--) {
    1160               0 :                 arg = va_arg(ap, zval **);
    1161               0 :                 convert_to_long_ex(arg);
    1162                 :         }
    1163                 : 
    1164               0 :         va_end(ap);
    1165               0 : }
    1166                 : /* }}} */
    1167                 : 
    1168                 : ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
    1169               0 : {
    1170                 :         zval **arg;
    1171                 :         va_list ap;
    1172                 : 
    1173               0 :         va_start(ap, argc);
    1174                 : 
    1175               0 :         while (argc--) {
    1176               0 :                 arg = va_arg(ap, zval **);
    1177               0 :                 convert_to_double_ex(arg);
    1178                 :         }
    1179                 : 
    1180               0 :         va_end(ap);
    1181               0 : }
    1182                 : /* }}} */
    1183                 : 
    1184                 : ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
    1185               0 : {
    1186                 :         zval **arg;
    1187                 :         va_list ap;
    1188                 : 
    1189               0 :         va_start(ap, argc);
    1190                 : 
    1191               0 :         while (argc--) {
    1192               0 :                 arg = va_arg(ap, zval **);
    1193               0 :                 convert_to_string_ex(arg);
    1194                 :         }
    1195                 : 
    1196               0 :         va_end(ap);
    1197               0 : }
    1198                 : /* }}} */
    1199                 : 
    1200                 : ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1201         4535335 : {
    1202                 :         zval op1_copy, op2_copy;
    1203         4535335 :         int converted = 0;
    1204                 : 
    1205                 :         while (1) {
    1206         4535795 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1207                 :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
    1208         3732543 :                                 long lval = Z_LVAL_P(op1) + Z_LVAL_P(op2);
    1209                 : 
    1210                 :                                 /* check for overflow by comparing sign bits */
    1211         3732896 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
    1212                 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
    1213                 : 
    1214             353 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
    1215                 :                                 } else {
    1216         3732190 :                                         ZVAL_LONG(result, lval);
    1217                 :                                 }
    1218         3732543 :                                 return SUCCESS;
    1219                 :                         }
    1220                 : 
    1221                 :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1222             237 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
    1223             237 :                                 return SUCCESS;
    1224                 : 
    1225                 :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1226          802316 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
    1227          802316 :                                 return SUCCESS;
    1228                 : 
    1229                 :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1230             229 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
    1231             229 :                                 return SUCCESS;
    1232                 : 
    1233                 :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY): {
    1234                 :                                 zval *tmp;
    1235                 : 
    1236               6 :                                 if ((result == op1) && (result == op2)) {
    1237                 :                                         /* $a += $a */
    1238               1 :                                         return SUCCESS;
    1239                 :                                 }
    1240               5 :                                 if (result != op1) {
    1241               4 :                                         *result = *op1;
    1242               4 :                                         zval_copy_ctor(result);
    1243                 :                                 }
    1244               5 :                                 zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
    1245               5 :                                 return SUCCESS;
    1246                 :                         }
    1247                 : 
    1248                 :                         default:
    1249             464 :                                 if (!converted) {
    1250             460 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1251             460 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1252             460 :                                         converted = 1;
    1253                 :                                 } else {
    1254               4 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1255               0 :                                         return FAILURE; /* unknown datatype */
    1256                 :                                 }
    1257                 :                 }
    1258             460 :         }
    1259                 : }
    1260                 : /* }}} */
    1261                 : 
    1262                 : ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1263          263205 : {
    1264                 :         zval op1_copy, op2_copy;
    1265          263205 :         int converted = 0;
    1266                 : 
    1267                 :         while (1) {
    1268          263438 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1269                 :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
    1270          245182 :                                 long lval = Z_LVAL_P(op1) - Z_LVAL_P(op2);
    1271                 : 
    1272                 :                                 /* check for overflow by comparing sign bits */
    1273          245198 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
    1274                 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
    1275                 : 
    1276              16 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
    1277                 :                                 } else {
    1278          245166 :                                         ZVAL_LONG(result, lval);
    1279                 :                                 }
    1280          245182 :                                 return SUCCESS;
    1281                 : 
    1282                 :                         }
    1283                 :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1284            2093 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
    1285            2093 :                                 return SUCCESS;
    1286                 : 
    1287                 :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1288             115 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
    1289             115 :                                 return SUCCESS;
    1290                 : 
    1291                 :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1292           15814 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
    1293           15814 :                                 return SUCCESS;
    1294                 : 
    1295                 :                         default:
    1296             234 :                                 if (!converted) {
    1297             233 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1298             233 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1299             233 :                                         converted = 1;
    1300                 :                                 } else {
    1301               1 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1302               0 :                                         return FAILURE; /* unknown datatype */
    1303                 :                                 }
    1304                 :                 }
    1305             233 :         }
    1306                 : }
    1307                 : /* }}} */
    1308                 : 
    1309                 : ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1310           13247 : {
    1311                 :         zval op1_copy, op2_copy;
    1312           13247 :         int converted = 0;
    1313                 : 
    1314                 :         while (1) {
    1315           13456 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1316                 :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
    1317                 :                                 long overflow;
    1318                 : 
    1319           12913 :                                 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
    1320           12913 :                                 Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG;
    1321           12913 :                                 return SUCCESS;
    1322                 : 
    1323                 :                         }
    1324                 :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1325              56 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
    1326              56 :                                 return SUCCESS;
    1327                 : 
    1328                 :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1329              68 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
    1330              68 :                                 return SUCCESS;
    1331                 : 
    1332                 :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1333             209 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
    1334             209 :                                 return SUCCESS;
    1335                 : 
    1336                 :                         default:
    1337             210 :                                 if (!converted) {
    1338             209 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1339             209 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1340             209 :                                         converted = 1;
    1341                 :                                 } else {
    1342               1 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1343               0 :                                         return FAILURE; /* unknown datatype */
    1344                 :                                 }
    1345                 :                 }
    1346             209 :         }
    1347                 : }
    1348                 : /* }}} */
    1349                 : 
    1350                 : ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1351         1611765 : {
    1352                 :         zval op1_copy, op2_copy;
    1353         1611765 :         int converted = 0;
    1354                 : 
    1355                 :         while (1) {
    1356         1611964 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1357                 :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1358         1308836 :                                 if (Z_LVAL_P(op2) == 0) {
    1359              30 :                                         zend_error(E_WARNING, "Division by zero");
    1360              30 :                                         ZVAL_BOOL(result, 0);
    1361              30 :                                         return FAILURE;                 /* division by zero */
    1362         1308806 :                                 } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
    1363                 :                                         /* Prevent overflow error/crash */
    1364               0 :                                         ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
    1365               0 :                                         return SUCCESS;
    1366                 :                                 }
    1367         1308806 :                                 if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
    1368          486814 :                                         ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
    1369                 :                                 } else {
    1370          821992 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
    1371                 :                                 }
    1372         1308806 :                                 return SUCCESS;
    1373                 : 
    1374                 :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1375          284821 :                                 if (Z_LVAL_P(op2) == 0) {
    1376              15 :                                         zend_error(E_WARNING, "Division by zero");
    1377              15 :                                         ZVAL_BOOL(result, 0);
    1378              15 :                                         return FAILURE;                 /* division by zero */
    1379                 :                                 }
    1380          284806 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
    1381          284806 :                                 return SUCCESS;
    1382                 : 
    1383                 :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1384            2037 :                                 if (Z_DVAL_P(op2) == 0) {
    1385               0 :                                         zend_error(E_WARNING, "Division by zero");
    1386               0 :                                         ZVAL_BOOL(result, 0);
    1387               0 :                                         return FAILURE;                 /* division by zero */
    1388                 :                                 }
    1389            2037 :                                 ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
    1390            2037 :                                 return SUCCESS;
    1391                 : 
    1392                 :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1393           16070 :                                 if (Z_DVAL_P(op2) == 0) {
    1394               0 :                                         zend_error(E_WARNING, "Division by zero");
    1395               0 :                                         ZVAL_BOOL(result, 0);
    1396               0 :                                         return FAILURE;                 /* division by zero */
    1397                 :                                 }
    1398           16070 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
    1399           16070 :                                 return SUCCESS;
    1400                 : 
    1401                 :                         default:
    1402             200 :                                 if (!converted) {
    1403             199 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1404             199 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1405             199 :                                         converted = 1;
    1406                 :                                 } else {
    1407               1 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1408               0 :                                         return FAILURE; /* unknown datatype */
    1409                 :                                 }
    1410                 :                 }
    1411             199 :         }
    1412                 : }
    1413                 : /* }}} */
    1414                 : 
    1415                 : ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1416           49529 : {
    1417                 :         zval op1_copy, op2_copy;
    1418                 : 
    1419           49529 :         zendi_convert_to_long(op1, op1_copy, result);
    1420           49529 :         zendi_convert_to_long(op2, op2_copy, result);
    1421                 : 
    1422           49529 :         if (Z_LVAL_P(op2) == 0) {
    1423              43 :                 zend_error(E_WARNING, "Division by zero");
    1424              43 :                 ZVAL_BOOL(result, 0);
    1425              43 :                 return FAILURE;                 /* modulus by zero */
    1426                 :         }
    1427                 : 
    1428           49486 :         if (Z_LVAL_P(op2) == -1) {
    1429                 :                 /* Prevent overflow error/crash if op1==LONG_MIN */
    1430               3 :                 ZVAL_LONG(result, 0);
    1431               3 :                 return SUCCESS;
    1432                 :         }
    1433                 : 
    1434           49483 :         ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
    1435           49483 :         return SUCCESS;
    1436                 : }
    1437                 : /* }}} */
    1438                 : 
    1439                 : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1440               0 : {
    1441                 :         zval op1_copy, op2_copy;
    1442                 : 
    1443               0 :         zendi_convert_to_boolean(op1, op1_copy, result);
    1444               0 :         zendi_convert_to_boolean(op2, op2_copy, result);
    1445               0 :         ZVAL_BOOL(result, Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
    1446               0 :         return SUCCESS;
    1447                 : }
    1448                 : /* }}} */
    1449                 : 
    1450                 : ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1451         6845915 : {
    1452                 :         zval op1_copy;
    1453                 : 
    1454         6845915 :         zendi_convert_to_boolean(op1, op1_copy, result);
    1455         6845915 :         ZVAL_BOOL(result, !Z_LVAL_P(op1));
    1456         6845915 :         return SUCCESS;
    1457                 : }
    1458                 : /* }}} */
    1459                 : 
    1460                 : ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1461             101 : {
    1462             101 :         zval op1_copy = *op1;
    1463                 : 
    1464             101 :         op1 = &op1_copy;
    1465                 : 
    1466             101 :         if (Z_TYPE_P(op1) == IS_LONG) {
    1467              84 :                 ZVAL_LONG(result, ~Z_LVAL_P(op1));
    1468              84 :                 return SUCCESS;
    1469              17 :         } else if (Z_TYPE_P(op1) == IS_DOUBLE) {
    1470               1 :                 ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
    1471               1 :                 return SUCCESS;
    1472              16 :         } else if (Z_TYPE_P(op1) == IS_STRING) {
    1473                 :                 int i;
    1474                 : 
    1475              15 :                 Z_TYPE_P(result) = IS_STRING;
    1476              15 :                 Z_STRVAL_P(result) = estrndup(Z_STRVAL_P(op1), Z_STRLEN_P(op1));
    1477              15 :                 Z_STRLEN_P(result) = Z_STRLEN_P(op1);
    1478              83 :                 for (i = 0; i < Z_STRLEN_P(op1); i++) {
    1479              68 :                         Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
    1480                 :                 }
    1481              15 :                 return SUCCESS;
    1482                 :         }
    1483               1 :         zend_error(E_ERROR, "Unsupported operand types");
    1484               0 :         return FAILURE;                         /* unknown datatype */
    1485                 : }
    1486                 : /* }}} */
    1487                 : 
    1488                 : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1489            7768 : {
    1490                 :         zval op1_copy, op2_copy;
    1491                 : 
    1492            7768 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1493                 :                 zval *longer, *shorter;
    1494                 :                 char *result_str;
    1495                 :                 int i, result_len;
    1496                 : 
    1497             200 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1498             117 :                         longer = op1;
    1499             117 :                         shorter = op2;
    1500                 :                 } else {
    1501              83 :                         longer = op2;
    1502              83 :                         shorter = op1;
    1503                 :                 }
    1504                 : 
    1505             200 :                 Z_TYPE_P(result) = IS_STRING;
    1506             200 :                 result_len = Z_STRLEN_P(longer);
    1507             200 :                 result_str = estrndup(Z_STRVAL_P(longer), Z_STRLEN_P(longer));
    1508             888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1509             688 :                         result_str[i] |= Z_STRVAL_P(shorter)[i];
    1510                 :                 }
    1511             200 :                 if (result==op1) {
    1512               1 :                         STR_FREE(Z_STRVAL_P(result));
    1513                 :                 }
    1514             200 :                 Z_STRVAL_P(result) = result_str;
    1515             200 :                 Z_STRLEN_P(result) = result_len;
    1516             200 :                 return SUCCESS;
    1517                 :         }
    1518                 : 
    1519            7568 :         if (Z_TYPE_P(op1) == IS_UNICODE && Z_TYPE_P(op2) == IS_UNICODE) {
    1520               0 :                 zend_error(E_ERROR, "Unsupported operand types");
    1521               0 :                 return FAILURE;
    1522                 :         }
    1523                 : 
    1524            7568 :         zendi_convert_to_long(op1, op1_copy, result);
    1525            7568 :         zendi_convert_to_long(op2, op2_copy, result);
    1526                 : 
    1527            7568 :         ZVAL_LONG(result, Z_LVAL_P(op1) | Z_LVAL_P(op2));
    1528            7568 :         return SUCCESS;
    1529                 : }
    1530                 : /* }}} */
    1531                 : 
    1532                 : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1533           44234 : {
    1534                 :         zval op1_copy, op2_copy;
    1535                 : 
    1536           44234 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1537                 :                 zval *longer, *shorter;
    1538                 :                 char *result_str;
    1539                 :                 int i, result_len;
    1540                 : 
    1541             201 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1542             117 :                         longer = op1;
    1543             117 :                         shorter = op2;
    1544                 :                 } else {
    1545              84 :                         longer = op2;
    1546              84 :                         shorter = op1;
    1547                 :                 }
    1548                 : 
    1549             201 :                 Z_TYPE_P(result) = IS_STRING;
    1550             201 :                 result_len = Z_STRLEN_P(shorter);
    1551             201 :                 result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
    1552             888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1553             687 :                         result_str[i] &= Z_STRVAL_P(longer)[i];
    1554                 :                 }
    1555             201 :                 if (result==op1) {
    1556               1 :                         STR_FREE(Z_STRVAL_P(result));
    1557                 :                 }
    1558             201 :                 Z_STRVAL_P(result) = result_str;
    1559             201 :                 Z_STRLEN_P(result) = result_len;
    1560             201 :                 return SUCCESS;
    1561                 :         }
    1562                 : 
    1563           44033 :         if (Z_TYPE_P(op1) == IS_UNICODE && Z_TYPE_P(op2) == IS_UNICODE) {
    1564               0 :                 zend_error(E_ERROR, "Unsupported operand types");
    1565               0 :                 return FAILURE;
    1566                 :         }
    1567                 : 
    1568           44033 :         zendi_convert_to_long(op1, op1_copy, result);
    1569           44033 :         zendi_convert_to_long(op2, op2_copy, result);
    1570                 : 
    1571           44033 :         ZVAL_LONG(result, Z_LVAL_P(op1) & Z_LVAL_P(op2));
    1572           44033 :         return SUCCESS;
    1573                 : }
    1574                 : /* }}} */
    1575                 : 
    1576                 : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1577             214 : {
    1578                 :         zval op1_copy, op2_copy;
    1579                 : 
    1580             214 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1581                 :                 zval *longer, *shorter;
    1582                 :                 char *result_str;
    1583                 :                 int i, result_len;
    1584                 : 
    1585             202 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1586             118 :                         longer = op1;
    1587             118 :                         shorter = op2;
    1588                 :                 } else {
    1589              84 :                         longer = op2;
    1590              84 :                         shorter = op1;
    1591                 :                 }
    1592                 : 
    1593             202 :                 Z_TYPE_P(result) = IS_STRING;
    1594             202 :                 result_len = Z_STRLEN_P(shorter);
    1595             202 :                 result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
    1596             892 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1597             690 :                         result_str[i] ^= Z_STRVAL_P(longer)[i];
    1598                 :                 }
    1599             202 :                 if (result==op1) {
    1600               1 :                         STR_FREE(Z_STRVAL_P(result));
    1601                 :                 }
    1602             202 :                 Z_STRVAL_P(result) = result_str;
    1603             202 :                 Z_STRLEN_P(result) = result_len;
    1604             202 :                 return SUCCESS;
    1605                 :         }
    1606                 : 
    1607              12 :         if (Z_TYPE_P(op1) == IS_UNICODE && Z_TYPE_P(op2) == IS_UNICODE) {
    1608               0 :                 zend_error(E_ERROR, "Unsupported operand types");
    1609               0 :                 return FAILURE;
    1610                 :         }
    1611                 : 
    1612              12 :         zendi_convert_to_long(op1, op1_copy, result);
    1613              12 :         zendi_convert_to_long(op2, op2_copy, result);
    1614                 : 
    1615              12 :         ZVAL_LONG(result, Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
    1616              12 :         return SUCCESS;
    1617                 : }
    1618                 : /* }}} */
    1619                 : 
    1620                 : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1621            3102 : {
    1622                 :         zval op1_copy, op2_copy;
    1623                 : 
    1624            3102 :         zendi_convert_to_long(op1, op1_copy, result);
    1625            3102 :         zendi_convert_to_long(op2, op2_copy, result);
    1626            3102 :         ZVAL_LONG(result, Z_LVAL_P(op1) << Z_LVAL_P(op2));
    1627            3102 :         return SUCCESS;
    1628                 : }
    1629                 : /* }}} */
    1630                 : 
    1631                 : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1632           35053 : {
    1633                 :         zval op1_copy, op2_copy;
    1634                 : 
    1635           35053 :         zendi_convert_to_long(op1, op1_copy, result);
    1636           35053 :         zendi_convert_to_long(op2, op2_copy, result);
    1637           35053 :         ZVAL_LONG(result, Z_LVAL_P(op1) >> Z_LVAL_P(op2));
    1638           35053 :         return SUCCESS;
    1639                 : }
    1640                 : /* }}} */
    1641                 : 
    1642                 : /* must support result==op1 */
    1643                 : ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1644          949572 : {
    1645          949572 :         if (Z_TYPE_P(op1) == IS_UNICODE) {
    1646          949060 :                 UChar32 codepoint = (UChar32) Z_LVAL_P(op2);
    1647                 : 
    1648          949060 :                 if (U_IS_BMP(codepoint)) {
    1649          949060 :                         Z_USTRLEN_P(result) = Z_USTRLEN_P(op1) + 1;
    1650          949060 :                         Z_USTRVAL_P(result) = eurealloc(Z_USTRVAL_P(op1), Z_USTRLEN_P(result)+1);
    1651          949060 :                         Z_USTRVAL_P(result)[Z_USTRLEN_P(result) - 1] = (UChar) Z_LVAL_P(op2);
    1652                 :                 } else {
    1653               0 :                         Z_USTRLEN_P(result) = Z_USTRLEN_P(op1) + 2;
    1654               0 :                         Z_USTRVAL_P(result) = eurealloc(Z_USTRVAL_P(op1), Z_USTRLEN_P(result)+1);
    1655               0 :                         Z_USTRVAL_P(result)[Z_USTRLEN_P(result) - 2] = (UChar) U16_LEAD(codepoint);
    1656               0 :                         Z_USTRVAL_P(result)[Z_USTRLEN_P(result) - 1] = (UChar) U16_TRAIL(codepoint);
    1657                 :                 }
    1658          949060 :                 Z_USTRVAL_P(result)[Z_USTRLEN_P(result)] = 0;
    1659          949060 :                 Z_TYPE_P(result) = IS_UNICODE;
    1660                 :         } else {
    1661             512 :                 Z_STRLEN_P(result) = Z_STRLEN_P(op1) + 1;
    1662             512 :                 Z_STRVAL_P(result) = (char *) erealloc(Z_STRVAL_P(op1), Z_STRLEN_P(result)+1);
    1663             512 :                 Z_STRVAL_P(result)[Z_STRLEN_P(result) - 1] = (char) Z_LVAL_P(op2);
    1664             512 :                 Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
    1665             512 :                 Z_TYPE_P(result) = Z_TYPE_P(op1);
    1666                 :         }
    1667          949572 :         return SUCCESS;
    1668                 : }
    1669                 : /* }}} */
    1670                 : 
    1671                 : /* must support result==op1 */
    1672                 : ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1673        12339147 : {
    1674        12339147 :         assert(Z_TYPE_P(op1) == Z_TYPE_P(op2));
    1675                 : 
    1676        12339147 :         if (Z_TYPE_P(op1) == IS_UNICODE) {
    1677        11422024 :                 int length = Z_USTRLEN_P(op1) + Z_USTRLEN_P(op2);
    1678                 : 
    1679        11422024 :                 Z_USTRVAL_P(result) = eurealloc(Z_USTRVAL_P(op1), length+1);
    1680        11422024 :                 u_memcpy(Z_USTRVAL_P(result)+Z_USTRLEN_P(op1), Z_USTRVAL_P(op2), Z_USTRLEN_P(op2));
    1681        11422024 :                 Z_USTRVAL_P(result)[length] = 0;
    1682        11422024 :                 Z_USTRLEN_P(result) = length;
    1683        11422024 :                 Z_TYPE_P(result) = IS_UNICODE;
    1684                 :         } else {
    1685          917123 :                 int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1686                 : 
    1687          917123 :                 Z_STRVAL_P(result) = (char *) erealloc(Z_STRVAL_P(op1), length+1);
    1688          917123 :                 memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1689          917123 :                 Z_STRVAL_P(result)[length] = 0;
    1690          917123 :                 Z_STRLEN_P(result) = length;
    1691          917123 :                 Z_TYPE_P(result) = Z_TYPE_P(op1);
    1692                 :         }
    1693        12339147 :         return SUCCESS;
    1694                 : }
    1695                 : /* }}} */
    1696                 : 
    1697                 : ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1698         3996640 : {
    1699                 :         zval op1_copy, op2_copy;
    1700         3996640 :         int use_copy1 = 0, use_copy2 = 0;
    1701                 :         zend_uchar result_type;
    1702                 : 
    1703         4964433 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1704          967793 :                 result_type = IS_STRING;
    1705                 :         } else {
    1706         3028847 :                 zend_make_unicode_zval(op1, &op1_copy, &use_copy1);
    1707         3028847 :                 zend_make_unicode_zval(op2, &op2_copy, &use_copy2);
    1708         3028847 :                 result_type = IS_UNICODE;
    1709                 :         }
    1710                 : 
    1711         3996640 :         if (use_copy1) {
    1712                 :                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1713                 :                  * we have to free it.
    1714                 :                  */
    1715           40325 :                 if (result == op1) {
    1716              20 :                         zval_dtor(op1);
    1717                 :                 }
    1718           40325 :                 op1 = &op1_copy;
    1719                 :         }
    1720         3996640 :         if (use_copy2) {
    1721           61530 :                 op2 = &op2_copy;
    1722                 :         }
    1723         3996640 :         if (result==op1) {      /* special case, perform operations on result */
    1724         3029386 :                 add_string_to_string(result, op1, op2);
    1725                 :         } else {
    1726          967254 :                 if (result_type == IS_UNICODE) {
    1727          892512 :                         Z_USTRLEN_P(result) = Z_USTRLEN_P(op1) + Z_USTRLEN_P(op2);
    1728          892512 :                         Z_USTRVAL_P(result) = eumalloc(Z_USTRLEN_P(result) + 1);
    1729          892512 :                         u_memcpy(Z_USTRVAL_P(result), Z_USTRVAL_P(op1), Z_USTRLEN_P(op1));
    1730          892512 :                         u_memcpy(Z_USTRVAL_P(result)+Z_USTRLEN_P(op1), Z_USTRVAL_P(op2), Z_USTRLEN_P(op2));
    1731          892512 :                         Z_USTRVAL_P(result)[Z_USTRLEN_P(result)] = 0;
    1732          892512 :                         Z_TYPE_P(result) = IS_UNICODE;
    1733                 :                 } else {
    1734           74742 :                         Z_STRLEN_P(result) = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1735           74742 :                         Z_STRVAL_P(result) = (char *) emalloc(Z_STRLEN_P(result) + 1);
    1736           74742 :                         memcpy(Z_STRVAL_P(result), Z_STRVAL_P(op1), Z_STRLEN_P(op1));
    1737           74742 :                         memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1738           74742 :                         Z_STRVAL_P(result)[Z_STRLEN_P(result)] = 0;
    1739           74742 :                         Z_TYPE_P(result) = result_type;
    1740                 :                 }
    1741                 :         }
    1742         3996640 :         if (use_copy1) {
    1743           40325 :                 zval_dtor(op1);
    1744                 :         }
    1745         3996640 :         if (use_copy2) {
    1746           61530 :                 zval_dtor(op2);
    1747                 :         }
    1748         3996640 :         return SUCCESS;
    1749                 : }
    1750                 : /* }}} */
    1751                 : 
    1752                 : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1753          692579 : {
    1754                 :         zval op1_copy, op2_copy;
    1755                 :         int use_copy1, use_copy2;
    1756                 : 
    1757          692579 :         zend_make_unicode_zval(op1, &op1_copy, &use_copy1);
    1758          692579 :         zend_make_unicode_zval(op2, &op2_copy, &use_copy2);
    1759                 : 
    1760          692579 :         if (use_copy1) {
    1761          425528 :                 op1 = &op1_copy;
    1762                 :         }
    1763          692579 :         if (use_copy2) {
    1764          501755 :                 op2 = &op2_copy;
    1765                 :         }
    1766                 : 
    1767          692579 :         ZVAL_LONG(result, zend_u_binary_zval_strcmp(op1, op2));
    1768                 : 
    1769          692579 :         if (use_copy1) {
    1770          425528 :                 zval_dtor(op1);
    1771                 :         }
    1772          692579 :         if (use_copy2) {
    1773          501755 :                 zval_dtor(op2);
    1774                 :         }
    1775          692579 :         return SUCCESS;
    1776                 : }
    1777                 : /* }}} */
    1778                 : 
    1779                 : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1780               0 : {
    1781                 :         zval op1_copy, op2_copy;
    1782                 :         int use_copy1, use_copy2;
    1783                 : 
    1784               0 :         zend_make_unicode_zval(op1, &op1_copy, &use_copy1);
    1785               0 :         zend_make_unicode_zval(op2, &op2_copy, &use_copy2);
    1786                 : 
    1787               0 :         if (use_copy1) {
    1788               0 :                 op1 = &op1_copy;
    1789                 :         }
    1790               0 :         if (use_copy2) {
    1791               0 :                 op2 = &op2_copy;
    1792                 :         }
    1793                 : 
    1794               0 :         Z_LVAL_P(result) = ucol_strcoll(UG(default_collator)->coll, Z_USTRVAL_P(op1), Z_USTRLEN_P(op1), Z_USTRVAL_P(op2), Z_USTRLEN_P(op2));
    1795               0 :         Z_TYPE_P(result) = IS_LONG;
    1796                 : 
    1797               0 :         if (use_copy1) {
    1798               0 :                 zval_dtor(op1);
    1799                 :         }
    1800               0 :         if (use_copy2) {
    1801               0 :                 zval_dtor(op2);
    1802                 :         }
    1803               0 :         return SUCCESS;
    1804                 : }
    1805                 : /* }}} */
    1806                 : 
    1807                 : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1808             926 : {
    1809                 :         zval op1_copy, op2_copy;
    1810                 : 
    1811             926 :         op1_copy = *op1;
    1812             926 :         zval_copy_ctor(&op1_copy);
    1813                 : 
    1814             926 :         op2_copy = *op2;
    1815             926 :         zval_copy_ctor(&op2_copy);
    1816                 : 
    1817             926 :         convert_to_double(&op1_copy);
    1818             926 :         convert_to_double(&op2_copy);
    1819                 : 
    1820             926 :         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
    1821                 : 
    1822             926 :         return SUCCESS;
    1823                 : }
    1824                 : /* }}} */
    1825                 : 
    1826                 : static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
    1827             413 : {
    1828             413 :         if (Z_REFCOUNT_P(op) == 0) {
    1829               1 :                 GC_REMOVE_ZVAL_FROM_BUFFER(op);
    1830               1 :                 zval_dtor(op);
    1831               1 :                 FREE_ZVAL(op);
    1832                 :         } else {
    1833             412 :                 zval_ptr_dtor(&op);
    1834                 :         }
    1835             413 : }
    1836                 : /* }}} */
    1837                 : 
    1838                 : ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1839        52549372 : {
    1840                 :         int ret;
    1841        52549372 :         int converted = 0;
    1842                 :         zval op1_copy, op2_copy;
    1843                 :         zval *op_free;
    1844                 : 
    1845                 :         while (1) {
    1846        52569916 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1847                 :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1848        46143774 :                                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1849        46143774 :                                 return SUCCESS;
    1850                 : 
    1851                 :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1852            7888 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
    1853            7888 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1854            7888 :                                 return SUCCESS;
    1855                 : 
    1856                 :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1857         5424143 :                                 Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
    1858         5424143 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1859         5424143 :                                 return SUCCESS;
    1860                 : 
    1861                 :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1862            1449 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    1863            1449 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1864            1449 :                                 return SUCCESS;
    1865                 : 
    1866                 :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
    1867             678 :                                 zend_compare_arrays(result, op1, op2 TSRMLS_CC);
    1868             678 :                                 return SUCCESS;
    1869                 : 
    1870                 :                         case TYPE_PAIR(IS_NULL, IS_NULL):
    1871             255 :                                 ZVAL_LONG(result, 0);
    1872             255 :                                 return SUCCESS;
    1873                 : 
    1874                 :                         case TYPE_PAIR(IS_NULL, IS_BOOL):
    1875              24 :                                 ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
    1876              24 :                                 return SUCCESS;
    1877                 : 
    1878                 :                         case TYPE_PAIR(IS_BOOL, IS_NULL):
    1879              30 :                                 ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
    1880              30 :                                 return SUCCESS;
    1881                 : 
    1882                 :                         case TYPE_PAIR(IS_BOOL, IS_BOOL):
    1883            4613 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1884            4613 :                                 return SUCCESS;
    1885                 : 
    1886                 :                         case TYPE_PAIR(IS_STRING, IS_STRING):
    1887            2552 :                                 zendi_smart_strcmp(result, op1, op2);
    1888            2552 :                                 return SUCCESS;
    1889                 : 
    1890                 :                         case TYPE_PAIR(IS_UNICODE, IS_UNICODE):
    1891          945476 :                                 zendi_u_smart_strcmp(result, op1, op2);
    1892          945476 :                                 return SUCCESS;
    1893                 : 
    1894                 :                         case TYPE_PAIR(IS_STRING, IS_UNICODE):
    1895             467 :                                 zendi_u_smart_strcmp(result, op1, op2);
    1896             467 :                                 return SUCCESS;
    1897                 : 
    1898                 :                         case TYPE_PAIR(IS_UNICODE, IS_STRING):
    1899             541 :                                 zendi_u_smart_strcmp(result, op1, op2);
    1900             541 :                                 return SUCCESS;
    1901                 : 
    1902                 :                         case TYPE_PAIR(IS_NULL, IS_STRING):
    1903             124 :                                 ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1904             124 :                                 return SUCCESS;
    1905                 : 
    1906                 :                         case TYPE_PAIR(IS_STRING, IS_NULL):
    1907               8 :                                 ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
    1908               8 :                                 return SUCCESS;
    1909                 : 
    1910                 :                         case TYPE_PAIR(IS_NULL, IS_UNICODE):
    1911             104 :                                 ZVAL_LONG(result, zend_u_binary_strcmp(EMPTY_STR, 0, Z_USTRVAL_P(op2), Z_USTRLEN_P(op2)));
    1912             104 :                                 return SUCCESS;
    1913                 : 
    1914                 :                         case TYPE_PAIR(IS_UNICODE, IS_NULL):
    1915             318 :                                 ZVAL_LONG(result, zend_u_binary_strcmp(Z_USTRVAL_P(op1), Z_USTRLEN_P(op1), EMPTY_STR, 0));
    1916             318 :                                 return SUCCESS;
    1917                 : 
    1918                 :                         case TYPE_PAIR(IS_OBJECT, IS_NULL):
    1919              48 :                                 ZVAL_LONG(result, 1);
    1920              48 :                                 return SUCCESS;
    1921                 : 
    1922                 :                         case TYPE_PAIR(IS_NULL, IS_OBJECT):
    1923              15 :                                 ZVAL_LONG(result, -1);
    1924              15 :                                 return SUCCESS;
    1925                 : 
    1926                 :                         case TYPE_PAIR(IS_OBJECT, IS_OBJECT):
    1927                 :                                 /* If both are objects sharing the same comparision handler then use is */
    1928             550 :                                 if (Z_OBJ_HANDLER_P(op1,compare_objects) == Z_OBJ_HANDLER_P(op2,compare_objects)) {
    1929             549 :                                         if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
    1930                 :                                                 /* object handles are identical, apprently this is the same object */
    1931              23 :                                                 ZVAL_LONG(result, 0);
    1932              23 :                                                 return SUCCESS;
    1933                 :                                         }
    1934             526 :                                         ZVAL_LONG(result, Z_OBJ_HT_P(op1)->compare_objects(op1, op2 TSRMLS_CC));
    1935             526 :                                         return SUCCESS;
    1936                 :                                 }
    1937                 :                                 /* break missing intentionally */
    1938                 : 
    1939                 :                         default:
    1940           36860 :                                 if (Z_TYPE_P(op1) == IS_OBJECT) {
    1941             217 :                                         if (Z_OBJ_HT_P(op1)->get) {
    1942               1 :                                                 op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
    1943               1 :                                                 ret = compare_function(result, op_free, op2 TSRMLS_CC);
    1944               1 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1945               1 :                                                 return ret;
    1946             216 :                                         } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
    1947             215 :                                                 ALLOC_INIT_ZVAL(op_free);
    1948             215 :                                                 if (Z_OBJ_HT_P(op1)->cast_object(op1, op_free, Z_TYPE_P(op2), NULL TSRMLS_CC) == FAILURE) {
    1949             112 :                                                         ZVAL_LONG(result, 1);
    1950             112 :                                                         zend_free_obj_get_result(op_free TSRMLS_CC);
    1951             112 :                                                         return SUCCESS;
    1952                 :                                                 }
    1953             103 :                                                 ret = compare_function(result, op_free, op2 TSRMLS_CC);
    1954             103 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1955             103 :                                                 return ret;
    1956                 :                                         }
    1957                 :                                 }
    1958           36644 :                                 if (Z_TYPE_P(op2) == IS_OBJECT) {
    1959             198 :                                         if (Z_OBJ_HT_P(op2)->get) {
    1960               0 :                                                 op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
    1961               0 :                                                 ret = compare_function(result, op1, op_free TSRMLS_CC);
    1962               0 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1963               0 :                                                 return ret;
    1964             198 :                                         } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
    1965             197 :                                                 ALLOC_INIT_ZVAL(op_free);
    1966             197 :                                                 if (Z_OBJ_HT_P(op2)->cast_object(op2, op_free, Z_TYPE_P(op1), NULL TSRMLS_CC) == FAILURE) {
    1967             107 :                                                         ZVAL_LONG(result, -1);
    1968             107 :                                                         zend_free_obj_get_result(op_free TSRMLS_CC);
    1969             107 :                                                         return SUCCESS;
    1970                 :                                                 }
    1971              90 :                                                 ret = compare_function(result, op1, op_free TSRMLS_CC);
    1972              90 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1973              90 :                                                 return ret;
    1974                 :                                         }
    1975                 :                                 }
    1976           36447 :                                 if (!converted) {
    1977           35896 :                                         if (Z_TYPE_P(op1) == IS_NULL) {
    1978            5426 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1979            5426 :                                                 ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
    1980            5426 :                                                 return SUCCESS;
    1981           30470 :                                         } else if (Z_TYPE_P(op2) == IS_NULL) {
    1982              94 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1983              94 :                                                 ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
    1984              94 :                                                 return SUCCESS;
    1985           30376 :                                         } else if (Z_TYPE_P(op1) == IS_BOOL) {
    1986            6494 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1987            6494 :                                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1988            6494 :                                                 return SUCCESS;
    1989           23882 :                                         } else if (Z_TYPE_P(op2) == IS_BOOL) {
    1990            3338 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1991            3338 :                                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1992            3338 :                                                 return SUCCESS;
    1993                 :                                         } else {
    1994           20544 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1995           20544 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1996           20544 :                                                 converted = 1;
    1997                 :                                         }
    1998             551 :                                 } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    1999             271 :                                         ZVAL_LONG(result, 1);
    2000             271 :                                         return SUCCESS;
    2001             280 :                                 } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    2002             280 :                                         ZVAL_LONG(result, -1);
    2003             280 :                                         return SUCCESS;
    2004               0 :                                 } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    2005               0 :                                         ZVAL_LONG(result, 1);
    2006               0 :                                         return SUCCESS;
    2007               0 :                                 } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    2008               0 :                                         ZVAL_LONG(result, -1);
    2009               0 :                                         return SUCCESS;
    2010                 :                                 } else {
    2011               0 :                                         ZVAL_LONG(result, 0);
    2012               0 :                                         return FAILURE;
    2013                 :                                 }
    2014                 :                 }
    2015           20544 :         }
    2016                 : }
    2017                 : /* }}} */
    2018                 : 
    2019                 : static int hash_zval_identical_function(const zval **z1, const zval **z2) /* {{{ */
    2020            1076 : {
    2021                 :         zval result;
    2022                 :         TSRMLS_FETCH();
    2023                 : 
    2024                 :         /* is_identical_function() returns 1 in case of identity and 0 in case
    2025                 :          * of a difference;
    2026                 :          * whereas this comparison function is expected to return 0 on identity,
    2027                 :          * and non zero otherwise.
    2028                 :          */
    2029            1076 :         if (is_identical_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    2030               0 :                 return 1;
    2031                 :         }
    2032            1076 :         return !Z_LVAL(result);
    2033                 : }
    2034                 : /* }}} */
    2035                 : 
    2036                 : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2037         2872404 : {
    2038         2872404 :         Z_TYPE_P(result) = IS_BOOL;
    2039         2872404 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    2040         1801542 :                 Z_LVAL_P(result) = 0;
    2041         1801542 :                 return SUCCESS;
    2042                 :         }
    2043         1070862 :         switch (Z_TYPE_P(op1)) {
    2044                 :                 case IS_NULL:
    2045            9676 :                         Z_LVAL_P(result) = 1;
    2046            9676 :                         break;
    2047                 :                 case IS_BOOL:
    2048                 :                 case IS_LONG:
    2049                 :                 case IS_RESOURCE:
    2050         1044574 :                         Z_LVAL_P(result) = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
    2051         1044574 :                         break;
    2052                 :                 case IS_DOUBLE:
    2053             184 :                         Z_LVAL_P(result) = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
    2054             184 :                         break;
    2055                 :                 case IS_STRING:
    2056              88 :                         Z_LVAL_P(result) = (Z_STRLEN_P(op1) == Z_STRLEN_P(op2))
    2057                 :                                 && (!memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)));
    2058              88 :                         break;
    2059                 :                 case IS_UNICODE:
    2060           16244 :                         Z_LVAL_P(result) = (Z_USTRLEN_P(op1) == Z_USTRLEN_P(op2))
    2061                 :                                 && (!memcmp(Z_USTRVAL_P(op1), Z_USTRVAL_P(op2), UBYTES(Z_USTRLEN_P(op1))));
    2062           16244 :                         break;
    2063                 :                 case IS_ARRAY:
    2064              63 :                         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;
    2065              63 :                         break;
    2066                 :                 case IS_OBJECT:
    2067              33 :                         if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
    2068              33 :                                 Z_LVAL_P(result) = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
    2069                 :                         } else {
    2070               0 :                                 Z_LVAL_P(result) = 0;
    2071                 :                         }
    2072              33 :                         break;
    2073                 :                 default:
    2074               0 :                         Z_LVAL_P(result) = 0;
    2075               0 :                         return FAILURE;
    2076                 :         }
    2077         1070862 :         return SUCCESS;
    2078                 : }
    2079                 : /* }}} */
    2080                 : 
    2081                 : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2082               0 : {
    2083               0 :         if (is_identical_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2084               0 :                 return FAILURE;
    2085                 :         }
    2086               0 :         Z_LVAL_P(result) = !Z_LVAL_P(result);
    2087               0 :         return SUCCESS;
    2088                 : }
    2089                 : /* }}} */
    2090                 : 
    2091                 : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2092          345618 : {
    2093          345618 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2094               0 :                 return FAILURE;
    2095                 :         }
    2096          345618 :         ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
    2097          345618 :         return SUCCESS;
    2098                 : }
    2099                 : /* }}} */
    2100                 : 
    2101                 : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2102               0 : {
    2103               0 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2104               0 :                 return FAILURE;
    2105                 :         }
    2106               0 :         ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
    2107               0 :         return SUCCESS;
    2108                 : }
    2109                 : /* }}} */
    2110                 : 
    2111                 : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2112            1898 : {
    2113            1898 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2114               0 :                 return FAILURE;
    2115                 :         }
    2116            1898 :         ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
    2117            1898 :         return SUCCESS;
    2118                 : }
    2119                 : /* }}} */
    2120                 : 
    2121                 : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2122            1277 : {
    2123            1277 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2124               0 :                 return FAILURE;
    2125                 :         }
    2126            1277 :         ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
    2127            1277 :         return SUCCESS;
    2128                 : }
    2129                 : /* }}} */
    2130                 : 
    2131                 : ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC) /* {{{ */
    2132          346380 : {
    2133                 :         zend_uint i;
    2134                 : 
    2135          521917 :         for (i=0; i<instance_ce->num_interfaces; i++) {
    2136          195588 :                 if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) {
    2137           20051 :                         return 1;
    2138                 :                 }
    2139                 :         }
    2140          326329 :         if (!interfaces_only) {
    2141          855035 :                 while (instance_ce) {
    2142          335810 :                         if (instance_ce == ce) {
    2143          133427 :                                 return 1;
    2144                 :                         }
    2145          202383 :                         instance_ce = instance_ce->parent;
    2146                 :                 }
    2147                 :         }
    2148                 : 
    2149          192902 :         return 0;
    2150                 : }
    2151                 : /* }}} */
    2152                 : 
    2153                 : ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC) /* {{{ */
    2154          328404 : {
    2155          328404 :         return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
    2156                 : }
    2157                 : /* }}} */
    2158                 : 
    2159                 : #define LOWER_CASE 1
    2160                 : #define UPPER_CASE 2
    2161                 : #define NUMERIC 3
    2162                 : 
    2163                 : static void increment_string(zval *str) /* {{{ */
    2164               0 : {
    2165               0 :         int carry=0;
    2166               0 :         int pos=Z_STRLEN_P(str)-1;
    2167               0 :         char *s=Z_STRVAL_P(str);
    2168                 :         char *t;
    2169               0 :         int last=0; /* Shut up the compiler warning */
    2170                 :         int ch;
    2171                 : 
    2172               0 :         if (Z_STRLEN_P(str) == 0) {
    2173               0 :                 STR_FREE(Z_STRVAL_P(str));
    2174               0 :                 Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1);
    2175               0 :                 Z_STRLEN_P(str) = 1;
    2176               0 :                 return;
    2177                 :         }
    2178                 : 
    2179               0 :         while (pos >= 0) {
    2180               0 :                 ch = s[pos];
    2181               0 :                 if (ch >= 'a' && ch <= 'z') {
    2182               0 :                         if (ch == 'z') {
    2183               0 :                                 s[pos] = 'a';
    2184               0 :                                 carry=1;
    2185                 :                         } else {
    2186               0 :                                 s[pos]++;
    2187               0 :                                 carry=0;
    2188                 :                         }
    2189               0 :                         last=LOWER_CASE;
    2190               0 :                 } else if (ch >= 'A' && ch <= 'Z') {
    2191               0 :                         if (ch == 'Z') {
    2192               0 :                                 s[pos] = 'A';
    2193               0 :                                 carry=1;
    2194                 :                         } else {
    2195               0 :                                 s[pos]++;
    2196               0 :                                 carry=0;
    2197                 :                         }
    2198               0 :                         last=UPPER_CASE;
    2199               0 :                 } else if (ch >= '0' && ch <= '9') {
    2200               0 :                         if (ch == '9') {
    2201               0 :                                 s[pos] = '0';
    2202               0 :                                 carry=1;
    2203                 :                         } else {
    2204               0 :                                 s[pos]++;
    2205               0 :                                 carry=0;
    2206                 :                         }
    2207               0 :                         last = NUMERIC;
    2208                 :                 } else {
    2209               0 :                         carry=0;
    2210               0 :                         break;
    2211                 :                 }
    2212               0 :                 if (carry == 0) {
    2213               0 :                         break;
    2214                 :                 }
    2215               0 :                 pos--;
    2216                 :         }
    2217                 : 
    2218               0 :         if (carry) {
    2219               0 :                 t = (char *) emalloc(Z_STRLEN_P(str)+1+1);
    2220               0 :                 memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str));
    2221               0 :                 Z_STRLEN_P(str)++;
    2222               0 :                 t[Z_STRLEN_P(str)] = '\0';
    2223               0 :                 switch (last) {
    2224                 :                         case NUMERIC:
    2225               0 :                                 t[0] = '1';
    2226               0 :                                 break;
    2227                 :                         case UPPER_CASE:
    2228               0 :                                 t[0] = 'A';
    2229               0 :                                 break;
    2230                 :                         case LOWER_CASE:
    2231               0 :                                 t[0] = 'a';
    2232                 :                                 break;
    2233                 :                 }
    2234               0 :                 STR_FREE(Z_STRVAL_P(str));
    2235               0 :                 Z_STRVAL_P(str) = t;
    2236                 :         }
    2237                 : }
    2238                 : /* }}} */
    2239                 : 
    2240                 : static void increment_unicode(zval *str) /* {{{ */
    2241              41 : {
    2242              41 :         int carry=0;
    2243              41 :         int pos=Z_USTRLEN_P(str)-1;
    2244              41 :         UChar *s=Z_USTRVAL_P(str);
    2245                 :         UChar *t;
    2246              41 :         int last=0; /* Shut up the compiler warning */
    2247                 :         int ch;
    2248                 : 
    2249              41 :         if (Z_USTRLEN_P(str) == 0) {
    2250               1 :                 USTR_FREE(Z_USTRVAL_P(str));
    2251               1 :                 ZVAL_ASCII_STRINGL(str, "1", sizeof("1")-1, 1);
    2252               1 :                 return;
    2253                 :         }
    2254                 : 
    2255              84 :         while (pos >= 0) {
    2256              44 :                 ch = s[pos];
    2257              76 :                 if (ch >= 'a' && ch <= 'z') {
    2258              32 :                         if (ch == 'z') {
    2259               2 :                                 s[pos] = 'a';
    2260               2 :                                 carry=1;
    2261                 :                         } else {
    2262              30 :                                 s[pos]++;
    2263              30 :                                 carry=0;
    2264                 :                         }
    2265              32 :                         last=LOWER_CASE;
    2266              18 :                 } else if (ch >= 'A' && ch <= 'Z') {
    2267               6 :                         if (ch == 'Z') {
    2268               0 :                                 s[pos] = 'A';
    2269               0 :                                 carry=1;
    2270                 :                         } else {
    2271               6 :                                 s[pos]++;
    2272               6 :                                 carry=0;
    2273                 :                         }
    2274               6 :                         last=UPPER_CASE;
    2275               8 :                 } else if (ch >= '0' && ch <= '9') {
    2276               2 :                         if (ch == '9') {
    2277               2 :                                 s[pos] = '0';
    2278               2 :                                 carry=1;
    2279                 :                         } else {
    2280               0 :                                 s[pos]++;
    2281               0 :                                 carry=0;
    2282                 :                         }
    2283               2 :                         last = NUMERIC;
    2284                 :                 } else {
    2285               4 :                         carry=0;
    2286               4 :                         break;
    2287                 :                 }
    2288              40 :                 if (carry == 0) {
    2289              36 :                         break;
    2290                 :                 }
    2291               4 :                 pos--;
    2292                 :         }
    2293                 : 
    2294              40 :         if (carry) {
    2295               0 :                 t = (UChar *) eumalloc(Z_USTRLEN_P(str)+1+1);
    2296               0 :                 memcpy(t+1, Z_USTRVAL_P(str), UBYTES(Z_USTRLEN_P(str)));
    2297               0 :                 Z_USTRLEN_P(str)++;
    2298               0 :                 t[Z_USTRLEN_P(str)] = 0;
    2299               0 :                 switch (last) {
    2300                 :                         case NUMERIC:
    2301               0 :                                 t[0] = '1';
    2302               0 :                                 break;
    2303                 :                         case UPPER_CASE:
    2304               0 :                                 t[0] = 'A';
    2305               0 :                                 break;
    2306                 :                         case LOWER_CASE:
    2307               0 :                                 t[0] = 'a';
    2308                 :                                 break;
    2309                 :                 }
    2310               0 :                 USTR_FREE(Z_USTRVAL_P(str));
    2311               0 :                 Z_USTRVAL_P(str) = t;
    2312                 :         }
    2313                 : }
    2314                 : /* }}} */
    2315                 : 
    2316                 : ZEND_API int increment_function(zval *op1) /* {{{ */
    2317        11944380 : {
    2318        11944380 :         switch (Z_TYPE_P(op1)) {
    2319                 :                 case IS_LONG:
    2320        11944187 :                         if (Z_LVAL_P(op1) == LONG_MAX) {
    2321                 :                                 /* switch to double */
    2322               2 :                                 double d = (double)Z_LVAL_P(op1);
    2323               2 :                                 ZVAL_DOUBLE(op1, d+1);
    2324                 :                         } else {
    2325        11944185 :                         Z_LVAL_P(op1)++;
    2326                 :                         }
    2327        11944187 :                         break;
    2328                 :                 case IS_DOUBLE:
    2329               1 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
    2330               1 :                         break;
    2331                 :                 case IS_NULL:
    2332              24 :                         ZVAL_LONG(op1, 1);
    2333              24 :                         break;
    2334                 :                 case IS_STRING: {
    2335                 :                                 long lval;
    2336                 :                                 double dval;
    2337                 : 
    2338               7 :                                 switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2339                 :                                         case IS_LONG:
    2340               7 :                                                 efree(Z_STRVAL_P(op1));
    2341               7 :                                                 if (lval == LONG_MAX) {
    2342                 :                                                         /* switch to double */
    2343               0 :                                                         double d = (double)lval;
    2344               0 :                                                         ZVAL_DOUBLE(op1, d+1);
    2345                 :                                                 } else {
    2346               7 :                                                         ZVAL_LONG(op1, lval+1);
    2347                 :                                                 }
    2348               7 :                                                 break;
    2349                 :                                         case IS_DOUBLE:
    2350               0 :                                                 efree(Z_STRVAL_P(op1));
    2351               0 :                                                 ZVAL_DOUBLE(op1, dval+1);
    2352               0 :                                                 break;
    2353                 :                                         default:
    2354                 :                                                 /* Perl style string increment */
    2355               0 :                                                 increment_string(op1);
    2356                 :                                                 break;
    2357                 :                                 }
    2358                 :                         }
    2359               7 :                         break;
    2360                 :                 case IS_UNICODE: {
    2361                 :                                 long lval;
    2362                 :                                 double dval;
    2363                 : 
    2364             156 :                                 switch (is_numeric_unicode(Z_USTRVAL_P(op1), Z_USTRLEN_P(op1), &lval, &dval, 0)) {
    2365                 :                                         case IS_LONG:
    2366             108 :                                                 efree(Z_USTRVAL_P(op1));
    2367             108 :                                                 if (lval == LONG_MAX) {
    2368                 :                                                         /* switch to double */
    2369               1 :                                                         double d = (double)lval;
    2370               1 :                                                         ZVAL_DOUBLE(op1, d+1);
    2371                 :                                                 } else {
    2372             107 :                                                         ZVAL_LONG(op1, lval+1);
    2373                 :                                                 }
    2374             108 :                                                 break;
    2375                 :                                         case IS_DOUBLE:
    2376               7 :                                                 efree(Z_USTRVAL_P(op1));
    2377               7 :                                                 ZVAL_DOUBLE(op1, dval+1);
    2378               7 :                                                 break;
    2379                 :                                         default:
    2380                 :                                                 /* Perl style string increment */
    2381              41 :                                                 increment_unicode(op1);
    2382                 :                                                 break;
    2383                 :                                 }
    2384                 :                         }
    2385             156 :                         break;
    2386                 :                 default:
    2387               5 :                         return FAILURE;
    2388                 :         }
    2389        11944375 :         return SUCCESS;
    2390                 : }
    2391                 : /* }}} */
    2392                 : 
    2393                 : ZEND_API int decrement_function(zval *op1) /* {{{ */
    2394        15360550 : {
    2395                 :         long lval;
    2396                 :         double dval;
    2397                 : 
    2398        15360550 :         switch (Z_TYPE_P(op1)) {
    2399                 :                 case IS_LONG:
    2400         9524562 :                         if (Z_LVAL_P(op1) == LONG_MIN) {
    2401               1 :                                 double d = (double)Z_LVAL_P(op1);
    2402               1 :                                 ZVAL_DOUBLE(op1, d-1);
    2403                 :                         } else {
    2404         9524561 :                         Z_LVAL_P(op1)--;
    2405                 :                         }
    2406         9524562 :                         break;
    2407                 :                 case IS_DOUBLE:
    2408         5835949 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
    2409         5835949 :                         break;
    2410                 :                 case IS_STRING:         /* Like perl we only support string increment */
    2411               0 :                         if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
    2412               0 :                                 STR_FREE(Z_STRVAL_P(op1));
    2413               0 :                                 ZVAL_LONG(op1, -1);
    2414               0 :                                 break;
    2415                 :                         }
    2416               0 :                         switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2417                 :                                 case IS_LONG:
    2418               0 :                                         STR_FREE(Z_STRVAL_P(op1));
    2419               0 :                                         if (lval == LONG_MIN) {
    2420               0 :                                                 double d = (double)lval;
    2421               0 :                                                 ZVAL_DOUBLE(op1, d-1);
    2422                 :                                         } else {
    2423               0 :                                                 ZVAL_LONG(op1, lval-1);
    2424                 :                                         }
    2425               0 :                                         break;
    2426                 :                                 case IS_DOUBLE:
    2427               0 :                                         STR_FREE(Z_STRVAL_P(op1));
    2428               0 :                                         ZVAL_DOUBLE(op1, dval - 1);
    2429                 :                                         break;
    2430                 :                         }
    2431               0 :                         break;
    2432                 :                 case IS_UNICODE:
    2433              33 :                         if (Z_USTRLEN_P(op1) == 0) { /* consider as 0 */
    2434               1 :                                 USTR_FREE(Z_USTRVAL_P(op1));
    2435               1 :                                 ZVAL_LONG(op1, -1);
    2436               1 :                                 break;
    2437                 :                         }
    2438              32 :                         switch (is_numeric_unicode(Z_USTRVAL_P(op1), Z_USTRLEN_P(op1), &lval, &dval, 0)) {
    2439                 :                                 case IS_LONG:
    2440               8 :                                         USTR_FREE(Z_USTRVAL_P(op1));
    2441               8 :                                         if (lval == LONG_MIN) {
    2442               1 :                                                 double d = (double)lval;
    2443               1 :                                                 ZVAL_DOUBLE(op1, d-1);
    2444                 :                                         } else {
    2445               7 :                                                 ZVAL_LONG(op1, lval-1);
    2446                 :                                         }
    2447               8 :                                         break;
    2448                 :                                 case IS_DOUBLE:
    2449               7 :                                         USTR_FREE(Z_USTRVAL_P(op1));
    2450               7 :                                         ZVAL_DOUBLE(op1, dval - 1);
    2451                 :                                         break;
    2452                 :                         }
    2453              32 :                         break;
    2454                 :                 default:
    2455               6 :                         return FAILURE;
    2456                 :         }
    2457                 : 
    2458        15360544 :         return SUCCESS;
    2459                 : }
    2460                 : /* }}} */
    2461                 : 
    2462                 : ZEND_API int zval_is_true(zval *op) /* {{{ */
    2463            3431 : {
    2464            3431 :         convert_to_boolean(op);
    2465            3431 :         return (Z_LVAL_P(op) ? 1 : 0);
    2466                 : }
    2467                 : /* }}} */
    2468                 : 
    2469                 : #ifdef ZEND_USE_TOLOWER_L
    2470                 : ZEND_API void zend_update_current_locale(void) /* {{{ */
    2471                 : {
    2472                 :         current_locale = _get_current_locale();
    2473                 : }
    2474                 : /* }}} */
    2475                 : #endif
    2476                 : 
    2477                 : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) /* {{{ */
    2478        57309660 : {
    2479        57309660 :         register unsigned char *str = (unsigned char*)source;
    2480        57309660 :         register unsigned char *result = (unsigned char*)dest;
    2481        57309660 :         register unsigned char *end = str + length;
    2482                 : 
    2483       815912359 :         while (str < end) {
    2484       701293039 :                 *result++ = zend_tolower((int)*str++);
    2485                 :         }
    2486        57309660 :         *result = '\0';
    2487                 : 
    2488        57309660 :         return dest;
    2489                 : }
    2490                 : /* }}} */
    2491                 : 
    2492                 : ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length) /* {{{ */
    2493        57309630 : {
    2494        57309630 :         return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
    2495                 : }
    2496                 : /* }}} */
    2497                 : 
    2498                 : ZEND_API zstr zend_u_str_tolower_copy(zend_uchar type, zstr dest, zstr source, unsigned int length) /* {{{ */
    2499           14489 : {
    2500           14489 :         if (type == IS_UNICODE) {
    2501           14489 :                 register UChar *str = source.u;
    2502           14489 :                 register UChar *result = dest.u;
    2503           14489 :                 register UChar *end = str + length;
    2504                 : 
    2505          138739 :                 while (str < end) {
    2506          109761 :                         *result++ = u_tolower((int)*str++);
    2507                 :                 }
    2508           14489 :                 *result = '\0';
    2509                 : 
    2510           14489 :                 return dest;
    2511                 :         } else {
    2512                 :                 zstr ret;
    2513                 : 
    2514               0 :                 ret.s = zend_str_tolower_copy(dest.s, source.s, length);
    2515               0 :                 return ret;
    2516                 :         }
    2517                 : }
    2518                 : /* }}} */
    2519                 : 
    2520                 : ZEND_API zstr zend_u_str_tolower_dup(zend_uchar type, zstr source, unsigned int length) /* {{{ */
    2521           14489 : {
    2522                 :         zstr ret;
    2523                 : 
    2524           14489 :         if (type == IS_UNICODE) {
    2525           14489 :                 ret.u = eumalloc(length+1);
    2526           14489 :                 ret = zend_u_str_tolower_copy(IS_UNICODE, ret, source, length);
    2527                 :         } else {
    2528               0 :                 ret.s = zend_str_tolower_copy((char*)emalloc(length+1), source.s, length);
    2529                 :         }
    2530           14489 :         return ret;
    2531                 : }
    2532                 : /* }}} */
    2533                 : 
    2534                 : ZEND_API void zend_str_tolower(char *str, unsigned int length) /* {{{ */
    2535          775246 : {
    2536          775246 :         register unsigned char *p = (unsigned char*)str;
    2537          775246 :         register unsigned char *end = p + length;
    2538                 : 
    2539         7806627 :         while (p < end) {
    2540         6256135 :                 *p = zend_tolower((int)*p);
    2541         6256135 :                 p++;
    2542                 :         }
    2543          775246 : }
    2544                 : /* }}} */
    2545                 : 
    2546                 : ZEND_API void zend_u_str_tolower(zend_uchar type, zstr str, unsigned int length) /* {{{ */
    2547              51 : {
    2548              51 :         if (type == IS_UNICODE) {
    2549              51 :                 register UChar *p = str.u;
    2550              51 :                 register UChar *end = p + length;
    2551                 : 
    2552             936 :                 while (p < end) {
    2553             834 :                         *p = u_tolower((int)*p);
    2554             834 :                         p++;
    2555                 :                 }
    2556                 :         } else {
    2557               0 :                 zend_str_tolower(str.s, length);
    2558                 :         }
    2559              51 : }
    2560                 : /* }}} */
    2561                 : 
    2562                 : ZEND_API zstr zend_u_str_case_fold(zend_uchar type, zstr source, unsigned int length, zend_bool normalize, unsigned int *new_len) /* {{{ */
    2563        29740342 : {
    2564                 :         zstr ret;
    2565                 : 
    2566        29740342 :         if (type == IS_UNICODE) {
    2567        29732649 :                 int ret_len = length;
    2568                 : 
    2569        29732649 :                 if (normalize) {
    2570         1470375 :                         if (zend_normalize_identifier(&ret.u, &ret_len, source.u, length, 1) == FAILURE) {
    2571               0 :                                 zend_error(E_NOTICE, "Could not normalize identifier");
    2572               0 :                                 ret.u = eustrndup(source.u, length);
    2573                 :                         }
    2574                 :                 } else {
    2575        28262274 :                         UErrorCode status = U_ZERO_ERROR;
    2576                 : 
    2577        28262274 :                         zend_case_fold_string(&ret.u, &ret_len, source.u, length, U_FOLD_CASE_DEFAULT, &status);
    2578        28262274 :                         if (U_FAILURE(status)) {
    2579               0 :                                 zend_error(E_NOTICE, "Could not case-fold string");
    2580               0 :                                 ret.u = eustrndup(source.u, length);
    2581                 :                         }
    2582                 :                 }
    2583                 : 
    2584        29732649 :                 *new_len = ret_len;
    2585                 :         } else {
    2586            7693 :                 *new_len = length;
    2587            7693 :                 ret.s = zend_str_tolower_dup(source.s, length);
    2588                 :         }
    2589        29740342 :         return ret;
    2590                 : }
    2591                 : /* }}} */
    2592                 : 
    2593                 : ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
    2594         4492365 : {
    2595                 :         int retval;
    2596                 : 
    2597         4492365 :         retval = memcmp(s1, s2, MIN(len1, len2));
    2598         4492365 :         if (!retval) {
    2599         1392260 :                 return (len1 - len2);
    2600                 :         } else {
    2601         3100105 :                 return retval;
    2602                 :         }
    2603                 : }
    2604                 : /* }}} */
    2605                 : 
    2606                 : ZEND_API int zend_u_binary_strcmp(UChar *s1, int len1, UChar *s2, int len2) /* {{{ */
    2607         1558537 : {
    2608         1558537 :         int result = u_strCompare(s1, len1, s2, len2, 1);
    2609         1558537 :         return ZEND_NORMALIZE_BOOL(result);
    2610                 : }
    2611                 : /* }}} */
    2612                 : 
    2613                 : ZEND_API int zend_binary_strncmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
    2614               1 : {
    2615                 :         int retval;
    2616                 : 
    2617               1 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    2618               1 :         if (!retval) {
    2619               1 :                 return (MIN(length, len1) - MIN(length, len2));
    2620                 :         } else {
    2621               0 :                 return retval;
    2622                 :         }
    2623                 : }
    2624                 : /* }}} */
    2625                 : 
    2626                 : ZEND_API int zend_u_binary_strncmp(UChar *s1, int len1, UChar *s2, int len2, uint length) /* {{{ */
    2627           11841 : {
    2628           11841 :         int32_t off1 = 0, off2 = 0;
    2629                 :         UChar32 c1, c2;
    2630           11841 :         int result = 0;
    2631                 : 
    2632          102957 :         for( ; length > 0; --length) {
    2633           91532 :                 if (off1 >= len1 || off2 >= len2) {
    2634             181 :                         result = len1 - len2;
    2635             181 :                         return ZEND_NORMALIZE_BOOL(result);
    2636                 :                 }
    2637           91351 :                 U16_NEXT(s1, off1, len1, c1);
    2638           91351 :                 U16_NEXT(s2, off2, len2, c2);
    2639           91351 :                 if (c1 != c2) {
    2640             235 :                         result = (int32_t)c1-(int32_t)c2;
    2641             235 :                         return ZEND_NORMALIZE_BOOL(result);
    2642                 :                 }
    2643                 :         }
    2644                 : 
    2645           11425 :         return 0;
    2646                 : }
    2647                 : /* }}} */
    2648                 : 
    2649                 : ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
    2650           97689 : {
    2651                 :         int len;
    2652                 :         int c1, c2;
    2653                 : 
    2654           97689 :         len = MIN(len1, len2);
    2655                 : 
    2656          415591 :         while (len--) {
    2657          317902 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2658          317902 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2659          317902 :                 if (c1 != c2) {
    2660           97689 :                         return c1 - c2;
    2661                 :                 }
    2662                 :         }
    2663                 : 
    2664               0 :         return len1 - len2;
    2665                 : }
    2666                 : /* }}} */
    2667                 : 
    2668                 : ZEND_API int zend_u_binary_strcasecmp(UChar *s1, int len1, UChar *s2, int len2) /* {{{ */
    2669            1001 : {
    2670            1001 :         UErrorCode status = U_ZERO_ERROR;
    2671            1001 :         int result = u_strCaseCompare(s1, len1, s2, len2, U_COMPARE_CODE_POINT_ORDER, &status);
    2672            1001 :         return ZEND_NORMALIZE_BOOL(result);
    2673                 : }
    2674                 : /* }}} */
    2675                 : 
    2676                 : ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
    2677               0 : {
    2678                 :         int len;
    2679                 :         int c1, c2;
    2680                 : 
    2681               0 :         len = MIN(length, MIN(len1, len2));
    2682                 : 
    2683               0 :         while (len--) {
    2684               0 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2685               0 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2686               0 :                 if (c1 != c2) {
    2687               0 :                         return c1 - c2;
    2688                 :                 }
    2689                 :         }
    2690                 : 
    2691               0 :         return MIN(length, len1) - MIN(length, len2);
    2692                 : }
    2693                 : /* }}} */
    2694                 : 
    2695                 : /*
    2696                 :  * Because we do not know UChar offsets for the passed-in limit of the number of
    2697                 :  * codepoints to compare, we take a hit upfront by iterating over both strings
    2698                 :  * until we find them. Then we can simply use u_strCaseCompare().
    2699                 :  */
    2700                 : ZEND_API int zend_u_binary_strncasecmp(UChar *s1, int len1, UChar *s2, int len2, uint length) /* {{{ */
    2701           16526 : {
    2702           16526 :         UErrorCode status = U_ZERO_ERROR;
    2703           16526 :         int32_t off1 = 0, off2 = 0;
    2704                 :         int result;
    2705                 : 
    2706           16526 :         U16_FWD_N(s1, off1, len1, length);
    2707           16526 :         U16_FWD_N(s2, off2, len2, length);
    2708           16526 :         result = u_strCaseCompare(s1, off1, s2, off2, U_COMPARE_CODE_POINT_ORDER, &status);
    2709           16526 :         return ZEND_NORMALIZE_BOOL(result);
    2710                 : }
    2711                 : /* }}} */
    2712                 : 
    2713                 : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2714            2467 : {
    2715            2467 :         return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2716                 : }
    2717                 : /* }}} */
    2718                 : 
    2719                 : ZEND_API int zend_u_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2720         1331500 : {
    2721         1331500 :         return zend_u_binary_strcmp(Z_USTRVAL_P(s1), Z_USTRLEN_P(s1), Z_USTRVAL_P(s2), Z_USTRLEN_P(s2));
    2722                 : }
    2723                 : /* }}} */
    2724                 : 
    2725                 : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2726               0 : {
    2727               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));
    2728                 : }
    2729                 : /* }}} */
    2730                 : 
    2731                 : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
    2732               0 : {
    2733               0 :         return zend_binary_strcasecmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2734                 : }
    2735                 : /* }}} */
    2736                 : 
    2737                 : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2738               0 : {
    2739               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));
    2740                 : }
    2741                 : /* }}} */
    2742                 : 
    2743                 : ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
    2744            2552 : {
    2745                 :         int ret1, ret2;
    2746                 :         long lval1, lval2;
    2747                 :         double dval1, dval2;
    2748                 : 
    2749            2637 :         if ((ret1=is_numeric_string(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0)) &&
    2750                 :                 (ret2=is_numeric_string(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0))) {
    2751              87 :                 if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
    2752               2 :                         if (ret1!=IS_DOUBLE) {
    2753               0 :                                 dval1 = (double) lval1;
    2754               2 :                         } else if (ret2!=IS_DOUBLE) {
    2755               0 :                                 dval2 = (double) lval2;
    2756               2 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2757                 :                                 /* Both values overflowed and have the same sign,
    2758                 :                                  * so a numeric comparison would be inaccurate */
    2759               0 :                                 goto string_cmp;
    2760                 :                         }
    2761               2 :                         Z_DVAL_P(result) = dval1 - dval2;
    2762               2 :                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    2763                 :                 } else { /* they both have to be long's */
    2764              83 :                         ZVAL_LONG(result, lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0));
    2765                 :                 }
    2766                 :         } else {
    2767            2467 : string_cmp:
    2768            2467 :                 Z_LVAL_P(result) = zend_binary_zval_strcmp(s1, s2);
    2769            2467 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
    2770                 :         }
    2771            2552 : }
    2772                 : /* }}} */
    2773                 : 
    2774                 : ZEND_API void zendi_u_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
    2775          946484 : {
    2776                 :         int ret1, ret2;
    2777                 :         long lval1, lval2;
    2778                 :         double dval1, dval2;
    2779                 :         zval s1_copy, s2_copy;
    2780          946484 :         int use_copy1 = 0, use_copy2 = 0;
    2781                 : 
    2782          946484 :         if (Z_TYPE_P(s1) != IS_UNICODE || Z_TYPE_P(s2) != IS_UNICODE) {
    2783            1008 :                 zend_make_unicode_zval(s1, &s1_copy, &use_copy1);
    2784            1008 :                 zend_make_unicode_zval(s2, &s2_copy, &use_copy2);
    2785            1008 :                 if (use_copy1) {
    2786             467 :                         s1 = &s1_copy;
    2787                 :                 }
    2788            1008 :                 if (use_copy2) {
    2789             541 :                         s2 = &s2_copy;
    2790                 :                 }
    2791                 :         }
    2792                 : 
    2793         1254080 :         if ((ret1=is_numeric_unicode(Z_USTRVAL_P(s1), Z_USTRLEN_P(s1), &lval1, &dval1, 0)) &&
    2794                 :                 (ret2=is_numeric_unicode(Z_USTRVAL_P(s2), Z_USTRLEN_P(s2), &lval2, &dval2, 0))) {
    2795          408604 :                 if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
    2796          101008 :                         if (ret1!=IS_DOUBLE) {
    2797              24 :                                 dval1 = (double) lval1;
    2798          100984 :                         } else if (ret2!=IS_DOUBLE) {
    2799              20 :                                 dval2 = (double) lval2;
    2800          100964 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2801                 :                                 /* Both values overflowed and have the same sign,
    2802                 :                                  * so a numeric comparison would be inaccurate */
    2803               0 :                                 goto string_cmp;
    2804                 :                         }
    2805          101008 :                         Z_DVAL_P(result) = dval1 - dval2;
    2806          101008 :                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    2807                 :                 } else { /* they both have to be long's */
    2808          206588 :                         ZVAL_LONG(result, lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0));
    2809                 :                 }
    2810                 :         } else {
    2811          638888 : string_cmp:
    2812          638888 :                 Z_LVAL_P(result) = zend_u_binary_zval_strcmp(s1, s2);
    2813          638888 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
    2814                 :         }
    2815                 : 
    2816          946484 :         if (use_copy1) {
    2817             467 :                 zval_dtor(s1);
    2818                 :         }
    2819          946484 :         if (use_copy2) {
    2820             541 :                 zval_dtor(s2);
    2821                 :         }
    2822          946484 : }
    2823                 : /* }}} */
    2824                 : 
    2825                 : static int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC) /* {{{ */
    2826            2275 : {
    2827                 :         zval result;
    2828                 : 
    2829            2275 :         if (compare_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    2830               0 :                 return 1;
    2831                 :         }
    2832            2275 :         return Z_LVAL(result);
    2833                 : }
    2834                 : /* }}} */
    2835                 : 
    2836                 : ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2837             473 : {
    2838             473 :         return zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    2839                 : }
    2840                 : /* }}} */
    2841                 : 
    2842                 : ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2843             678 : {
    2844             678 :         ZVAL_LONG(result, zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC));
    2845             678 : }
    2846                 : /* }}} */
    2847                 : 
    2848                 : ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC) /* {{{ */
    2849             678 : {
    2850             678 :         zend_compare_symbol_tables(result, Z_ARRVAL_P(a1), Z_ARRVAL_P(a2) TSRMLS_CC);
    2851             678 : }
    2852                 : /* }}} */
    2853                 : 
    2854                 : ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
    2855               0 : {
    2856               0 :         Z_TYPE_P(result) = IS_LONG;
    2857                 : 
    2858               0 :         if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {
    2859               0 :                 Z_LVAL_P(result) = 0;
    2860               0 :                 return;
    2861                 :         }
    2862                 : 
    2863               0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2864               0 :                 Z_LVAL_P(result) = 1;
    2865                 :         } else {
    2866               0 :                 Z_LVAL_P(result) = Z_OBJ_HT_P(o1)->compare_objects(o1, o2 TSRMLS_CC);
    2867                 :         }
    2868                 : }
    2869                 : /* }}} */
    2870                 : 
    2871                 : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
    2872             667 : {
    2873                 :         TSRMLS_FETCH();
    2874                 : 
    2875             667 :         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
    2876             667 : }
    2877                 : /* }}} */
    2878                 : 
    2879                 : /*
    2880                 :  * Local variables:
    2881                 :  * tab-width: 4
    2882                 :  * c-basic-offset: 4
    2883                 :  * indent-tabs-mode: t
    2884                 :  * End:
    2885                 :  */

Generated by: LTP GCOV extension version 1.5

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

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