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

LCOV - code coverage report
Current view: top level - Zend - zend_operators.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 795 972 81.8 %
Date: 2014-04-18 Functions: 57 68 83.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Fri, 18 Apr 2014 07:01:23 +0000 (6 days ago)

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