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: 935 1094 85.5 %
Date: 2014-08-04 Functions: 68 74 91.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 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_strtod.h"
      31             : #include "zend_exceptions.h"
      32             : #include "zend_closures.h"
      33             : 
      34             : #if ZEND_USE_TOLOWER_L
      35             : #include <locale.h>
      36             : static _locale_t current_locale = NULL;
      37             : /* this is true global! may lead to strange effects on ZTS, but so may setlocale() */
      38             : #define zend_tolower(c) _tolower_l(c, current_locale)
      39             : #else
      40             : #define zend_tolower(c) tolower(c)
      41             : #endif
      42             : 
      43             : #define TYPE_PAIR(t1,t2) (((t1) << 4) | (t2))
      44             : 
      45             : static const unsigned char tolower_map[256] = {
      46             : 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
      47             : 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
      48             : 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
      49             : 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
      50             : 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
      51             : 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x5e,0x5f,
      52             : 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
      53             : 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
      54             : 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
      55             : 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
      56             : 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
      57             : 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
      58             : 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
      59             : 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
      60             : 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
      61             : 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
      62             : };
      63             : 
      64             : #define zend_tolower_ascii(c) (tolower_map[(unsigned char)(c)])
      65             : 
      66             : /**
      67             :  * Functions using locale lowercase:
      68             :                 zend_binary_strncasecmp_l
      69             :                 zend_binary_strcasecmp_l
      70             :                 zend_binary_zval_strcasecmp
      71             :                 zend_binary_zval_strncasecmp
      72             :                 string_compare_function_ex
      73             :                 string_case_compare_function
      74             :  * Functions using ascii lowercase:
      75             :                 zend_str_tolower_copy
      76             :                 zend_str_tolower_dup
      77             :                 zend_str_tolower
      78             :                 zend_binary_strcasecmp
      79             :                 zend_binary_strncasecmp
      80             :  */
      81             : 
      82       64294 : ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
      83             : {
      84             :         int retval;
      85             : 
      86       64294 :         if (!str_len) {
      87       42522 :                 str_len = strlen(str);
      88             :         }
      89       64294 :         retval = strtol(str, NULL, 0);
      90       64294 :         if (str_len>0) {
      91       43029 :                 switch (str[str_len-1]) {
      92             :                         case 'g':
      93             :                         case 'G':
      94           0 :                                 retval *= 1024;
      95             :                                 /* break intentionally missing */
      96             :                         case 'm':
      97             :                         case 'M':
      98           0 :                                 retval *= 1024;
      99             :                                 /* break intentionally missing */
     100             :                         case 'k':
     101             :                         case 'K':
     102           0 :                                 retval *= 1024;
     103             :                                 break;
     104             :                 }
     105             :         }
     106       64294 :         return retval;
     107             : }
     108             : /* }}} */
     109             : 
     110     1743628 : ZEND_API long zend_atol(const char *str, int str_len) /* {{{ */
     111             : {
     112             :         long retval;
     113             : 
     114     1743628 :         if (!str_len) {
     115       42395 :                 str_len = strlen(str);
     116             :         }
     117     1743628 :         retval = strtol(str, NULL, 0);
     118     1743628 :         if (str_len>0) {
     119     1701233 :                 switch (str[str_len-1]) {
     120             :                         case 'g':
     121             :                         case 'G':
     122           4 :                                 retval *= 1024;
     123             :                                 /* break intentionally missing */
     124             :                         case 'm':
     125             :                         case 'M':
     126       63751 :                                 retval *= 1024;
     127             :                                 /* break intentionally missing */
     128             :                         case 'k':
     129             :                         case 'K':
     130       85017 :                                 retval *= 1024;
     131             :                                 break;
     132             :                 }
     133             :         }
     134     1743628 :         return retval;
     135             : }
     136             : /* }}} */
     137             : 
     138           0 : ZEND_API double zend_string_to_double(const char *number, zend_uint length) /* {{{ */
     139             : {
     140           0 :         double divisor = 10.0;
     141           0 :         double result = 0.0;
     142             :         double exponent;
     143           0 :         const char *end = number+length;
     144           0 :         const char *digit = number;
     145             : 
     146           0 :         if (!length) {
     147           0 :                 return result;
     148             :         }
     149             : 
     150           0 :         while (digit < end) {
     151           0 :                 if ((*digit <= '9' && *digit >= '0')) {
     152           0 :                         result *= 10;
     153           0 :                         result += *digit - '0';
     154           0 :                 } else if (*digit == '.') {
     155           0 :                         digit++;
     156           0 :                         break;
     157           0 :                 } else if (toupper(*digit) == 'E') {
     158           0 :                         exponent = (double) atoi(digit+1);
     159           0 :                         result *= pow(10.0, exponent);
     160           0 :                         return result;
     161             :                 } else {
     162           0 :                         return result;
     163             :                 }
     164           0 :                 digit++;
     165             :         }
     166             : 
     167           0 :         while (digit < end) {
     168           0 :                 if ((*digit <= '9' && *digit >= '0')) {
     169           0 :                         result += (*digit - '0') / divisor;
     170           0 :                         divisor *= 10;
     171           0 :                 } else if (toupper(*digit) == 'E') {
     172           0 :                         exponent = (double) atoi(digit+1);
     173           0 :                         result *= pow(10.0, exponent);
     174           0 :                         return result;
     175             :                 } else {
     176           0 :                         return result;
     177             :                 }
     178           0 :                 digit++;
     179             :         }
     180           0 :         return result;
     181             : }
     182             : /* }}} */
     183             : 
     184      203346 : ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
     185             : {
     186      203346 :         switch (Z_TYPE_P(op)) {
     187             :                 case IS_STRING:
     188             :                         {
     189             :                                 char *strval;
     190             : 
     191      101122 :                                 strval = Z_STRVAL_P(op);
     192      101122 :                                 if ((Z_TYPE_P(op)=is_numeric_string(strval, Z_STRLEN_P(op), &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
     193          40 :                                         ZVAL_LONG(op, 0);
     194             :                                 }
     195      101122 :                                 str_efree(strval);
     196      101122 :                                 break;
     197             :                         }
     198             :                 case IS_BOOL:
     199          31 :                         Z_TYPE_P(op) = IS_LONG;
     200          31 :                         break;
     201             :                 case IS_RESOURCE:
     202           5 :                         zend_list_delete(Z_LVAL_P(op));
     203           5 :                         Z_TYPE_P(op) = IS_LONG;
     204           5 :                         break;
     205             :                 case IS_OBJECT:
     206           5 :                         convert_to_long_base(op, 10);
     207           5 :                         break;
     208             :                 case IS_NULL:
     209          45 :                         ZVAL_LONG(op, 0);
     210             :                         break;
     211             :         }
     212      203346 : }
     213             : /* }}} */
     214             : 
     215             : /* {{{ zendi_convert_scalar_to_number */
     216             : #define zendi_convert_scalar_to_number(op, holder, result)                      \
     217             :         if (op==result) {                                                                                               \
     218             :                 if (Z_TYPE_P(op) != IS_LONG) {                                                          \
     219             :                         convert_scalar_to_number(op TSRMLS_CC);                                 \
     220             :                 }                                                                                                                       \
     221             :         } else {                                                                                                                \
     222             :                 switch (Z_TYPE_P(op)) {                                                                         \
     223             :                         case IS_STRING:                                                                                 \
     224             :                                 {                                                                                                       \
     225             :                                         if ((Z_TYPE(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) {     \
     226             :                                                 ZVAL_LONG(&(holder), 0);                                                    \
     227             :                                         }                                                                                                               \
     228             :                                         (op) = &(holder);                                                                           \
     229             :                                         break;                                                                                                  \
     230             :                                 }                                                                                                                       \
     231             :                         case IS_BOOL:                                                                                                   \
     232             :                         case IS_RESOURCE:                                                                                               \
     233             :                                 ZVAL_LONG(&(holder), Z_LVAL_P(op));                                                 \
     234             :                                 (op) = &(holder);                                                                                   \
     235             :                                 break;                                                                                                          \
     236             :                         case IS_NULL:                                                                                                   \
     237             :                                 ZVAL_LONG(&(holder), 0);                                                                    \
     238             :                                 (op) = &(holder);                                                                                   \
     239             :                                 break;                                                                                                          \
     240             :                         case IS_OBJECT:                                                                                                 \
     241             :                                 (holder) = (*(op));                                                                                     \
     242             :                                 zval_copy_ctor(&(holder));                                                                  \
     243             :                                 convert_to_long_base(&(holder), 10);                                                \
     244             :                                 if (Z_TYPE(holder) == IS_LONG) {                                                        \
     245             :                                         (op) = &(holder);                                                                           \
     246             :                                 }                                                                                                                       \
     247             :                                 break;                                                                                                          \
     248             :                 }                                                                                                                                       \
     249             :         }
     250             : 
     251             : /* }}} */
     252             : 
     253             : /* {{{ zendi_convert_to_long */
     254             : #define zendi_convert_to_long(op, holder, result)                                       \
     255             :         if (op == result) {                                                                                             \
     256             :                 convert_to_long(op);                                                                            \
     257             :         } else if (Z_TYPE_P(op) != IS_LONG) {                                                   \
     258             :                 switch (Z_TYPE_P(op)) {                                                                         \
     259             :                         case IS_NULL:                                                                                   \
     260             :                                 Z_LVAL(holder) = 0;                                                                     \
     261             :                                 break;                                                                                          \
     262             :                         case IS_DOUBLE:                                                                                 \
     263             :                                 Z_LVAL(holder) = zend_dval_to_lval(Z_DVAL_P(op));       \
     264             :                                 break;                                                                                          \
     265             :                         case IS_STRING:                                                                                 \
     266             :                                 Z_LVAL(holder) = strtol(Z_STRVAL_P(op), NULL, 10);      \
     267             :                                 break;                                                                                          \
     268             :                         case IS_ARRAY:                                                                                  \
     269             :                                 Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);  \
     270             :                                 break;                                                                                          \
     271             :                         case IS_OBJECT:                                                                                 \
     272             :                                 (holder) = (*(op));                                                                     \
     273             :                                 zval_copy_ctor(&(holder));                                                  \
     274             :                                 convert_to_long_base(&(holder), 10);                                \
     275             :                                 break;                                                                                          \
     276             :                         case IS_BOOL:                                                                                   \
     277             :                         case IS_RESOURCE:                                                                               \
     278             :                                 Z_LVAL(holder) = Z_LVAL_P(op);                                          \
     279             :                                 break;                                                                                          \
     280             :                         default:                                                                                                \
     281             :                                 zend_error(E_WARNING, "Cannot convert to ordinal value");     \
     282             :                                 Z_LVAL(holder) = 0;                                                                     \
     283             :                                 break;                                                                                          \
     284             :                 }                                                                                                                       \
     285             :                 Z_TYPE(holder) = IS_LONG;                                                                       \
     286             :                 (op) = &(holder);                                                                                   \
     287             :         }
     288             : 
     289             : /* }}} */
     290             : 
     291             : /* {{{ zendi_convert_to_boolean */
     292             : #define zendi_convert_to_boolean(op, holder, result)                            \
     293             :         if (op==result) {                                                                                               \
     294             :                 convert_to_boolean(op);                                                                         \
     295             :         } else if (Z_TYPE_P(op) != IS_BOOL) {                                                   \
     296             :                 switch (Z_TYPE_P(op)) {                                                                         \
     297             :                         case IS_NULL:                                                                                   \
     298             :                                 Z_LVAL(holder) = 0;                                                                     \
     299             :                                 break;                                                                                          \
     300             :                         case IS_RESOURCE:                                                                               \
     301             :                         case IS_LONG:                                                                                   \
     302             :                                 Z_LVAL(holder) = (Z_LVAL_P(op) ? 1 : 0);                        \
     303             :                                 break;                                                                                          \
     304             :                         case IS_DOUBLE:                                                                                 \
     305             :                                 Z_LVAL(holder) = (Z_DVAL_P(op) ? 1 : 0);                        \
     306             :                                 break;                                                                                          \
     307             :                         case IS_STRING:                                                                                 \
     308             :                                 if (Z_STRLEN_P(op) == 0                                                         \
     309             :                                         || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {     \
     310             :                                         Z_LVAL(holder) = 0;                                                             \
     311             :                                 } else {                                                                                        \
     312             :                                         Z_LVAL(holder) = 1;                                                             \
     313             :                                 }                                                                                                       \
     314             :                                 break;                                                                                          \
     315             :                         case IS_ARRAY:                                                                                  \
     316             :                                 Z_LVAL(holder) = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);  \
     317             :                                 break;                                                                                          \
     318             :                         case IS_OBJECT:                                                                                 \
     319             :                                 (holder) = (*(op));                                                                     \
     320             :                                 zval_copy_ctor(&(holder));                                                  \
     321             :                                 convert_to_boolean(&(holder));                                              \
     322             :                                 break;                                                                                          \
     323             :                         default:                                                                                                \
     324             :                                 Z_LVAL(holder) = 0;                                                                     \
     325             :                                 break;                                                                                          \
     326             :                 }                                                                                                                       \
     327             :                 Z_TYPE(holder) = IS_BOOL;                                                                       \
     328             :                 (op) = &(holder);                                                                                   \
     329             :         }
     330             : 
     331             : /* }}} */
     332             : 
     333             : /* {{{ convert_object_to_type */
     334             : #define convert_object_to_type(op, ctype, conv_func)                                                                            \
     335             :         if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                           \
     336             :                 zval dst;                                                                                                                                                       \
     337             :                 if (Z_OBJ_HT_P(op)->cast_object(op, &dst, ctype TSRMLS_CC) == FAILURE) {                 \
     338             :                         zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
     339             :                                 "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name,            \
     340             :                         zend_get_type_by_const(ctype));                                                                                                 \
     341             :                 } else {                                                                                                                                                        \
     342             :                         zval_dtor(op);                                                                                                                                  \
     343             :                         Z_TYPE_P(op) = ctype;                                                                                                                   \
     344             :                         op->value = dst.value;                                                                                                                       \
     345             :                 }                                                                                                                                                                       \
     346             :         } else {                                                                                                                                                                \
     347             :                 if (Z_OBJ_HT_P(op)->get) {                                                                                                                   \
     348             :                         zval *newop = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);                                                             \
     349             :                         if (Z_TYPE_P(newop) != IS_OBJECT) {                                                                                             \
     350             :                                 /* for safety - avoid loop */                                                                                           \
     351             :                                 zval_dtor(op);                                                                                                                          \
     352             :                                 *op = *newop;                                                                                                                           \
     353             :                                 FREE_ZVAL(newop);                                                                                                                       \
     354             :                                 conv_func(op);                                                                                                                          \
     355             :                         }                                                                                                                                                               \
     356             :                 }                                                                                                                                                                       \
     357             :         }
     358             : 
     359             : /* }}} */
     360             : 
     361      645364 : ZEND_API void convert_to_long(zval *op) /* {{{ */
     362             : {
     363      645364 :         if (Z_TYPE_P(op) != IS_LONG) {
     364       63027 :                 convert_to_long_base(op, 10);
     365             :         }
     366      645364 : }
     367             : /* }}} */
     368             : 
     369       66754 : ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
     370             : {
     371             :         long tmp;
     372             : 
     373       66754 :         switch (Z_TYPE_P(op)) {
     374             :                 case IS_NULL:
     375        1303 :                         Z_LVAL_P(op) = 0;
     376        1303 :                         break;
     377             :                 case IS_RESOURCE: {
     378             :                                 TSRMLS_FETCH();
     379             : 
     380         124 :                                 zend_list_delete(Z_LVAL_P(op));
     381             :                         }
     382             :                         /* break missing intentionally */
     383             :                 case IS_BOOL:
     384             :                 case IS_LONG:
     385       10450 :                         break;
     386             :                 case IS_DOUBLE:
     387       11006 :                         Z_LVAL_P(op) = zend_dval_to_lval(Z_DVAL_P(op));
     388        5503 :                         break;
     389             :                 case IS_STRING:
     390             :                         {
     391       48590 :                                 char *strval = Z_STRVAL_P(op);
     392             : 
     393       48590 :                                 Z_LVAL_P(op) = strtol(strval, NULL, base);
     394       48590 :                                 str_efree(strval);
     395             :                         }
     396       48590 :                         break;
     397             :                 case IS_ARRAY:
     398         851 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     399             :                         zval_dtor(op);
     400         851 :                         Z_LVAL_P(op) = tmp;
     401         851 :                         break;
     402             :                 case IS_OBJECT:
     403             :                         {
     404          57 :                                 int retval = 1;
     405             :                                 TSRMLS_FETCH();
     406             : 
     407         114 :                                 convert_object_to_type(op, IS_LONG, convert_to_long);
     408             : 
     409          57 :                                 if (Z_TYPE_P(op) == IS_LONG) {
     410          57 :                                         return;
     411             :                                 }
     412           0 :                                 zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name);
     413             : 
     414             :                                 zval_dtor(op);
     415           0 :                                 ZVAL_LONG(op, retval);
     416           0 :                                 return;
     417             :                         }
     418             :                 default:
     419           0 :                         zend_error(E_WARNING, "Cannot convert to ordinal value");
     420             :                         zval_dtor(op);
     421           0 :                         Z_LVAL_P(op) = 0;
     422             :                         break;
     423             :         }
     424             : 
     425       66697 :         Z_TYPE_P(op) = IS_LONG;
     426             : }
     427             : /* }}} */
     428             : 
     429      195040 : ZEND_API void convert_to_double(zval *op) /* {{{ */
     430             : {
     431             :         double tmp;
     432             : 
     433      195040 :         switch (Z_TYPE_P(op)) {
     434             :                 case IS_NULL:
     435         316 :                         Z_DVAL_P(op) = 0.0;
     436         316 :                         break;
     437             :                 case IS_RESOURCE: {
     438             :                                 TSRMLS_FETCH();
     439             : 
     440          48 :                                 zend_list_delete(Z_LVAL_P(op));
     441             :                         }
     442             :                         /* break missing intentionally */
     443             :                 case IS_BOOL:
     444             :                 case IS_LONG:
     445      191098 :                         Z_DVAL_P(op) = (double) Z_LVAL_P(op);
     446      191098 :                         break;
     447             :                 case IS_DOUBLE:
     448        2407 :                         break;
     449             :                 case IS_STRING:
     450             :                         {
     451         847 :                                 char *strval = Z_STRVAL_P(op);
     452             : 
     453         847 :                                 Z_DVAL_P(op) = zend_strtod(strval, NULL);
     454         847 :                                 str_efree(strval);
     455             :                         }
     456         847 :                         break;
     457             :                 case IS_ARRAY:
     458         357 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     459             :                         zval_dtor(op);
     460         357 :                         Z_DVAL_P(op) = tmp;
     461         357 :                         break;
     462             :                 case IS_OBJECT:
     463             :                         {
     464          15 :                                 double retval = 1.0;
     465             :                                 TSRMLS_FETCH();
     466             : 
     467          30 :                                 convert_object_to_type(op, IS_DOUBLE, convert_to_double);
     468             : 
     469          15 :                                 if (Z_TYPE_P(op) == IS_DOUBLE) {
     470          15 :                                         return;
     471             :                                 }
     472           0 :                                 zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name);
     473             : 
     474             :                                 zval_dtor(op);
     475           0 :                                 ZVAL_DOUBLE(op, retval);
     476           0 :                                 break;
     477             :                         }
     478             :                 default:
     479           0 :                         zend_error(E_WARNING, "Cannot convert to real value (type=%d)", Z_TYPE_P(op));
     480             :                         zval_dtor(op);
     481           0 :                         Z_DVAL_P(op) = 0;
     482             :                         break;
     483             :         }
     484      195025 :         Z_TYPE_P(op) = IS_DOUBLE;
     485             : }
     486             : /* }}} */
     487             : 
     488         914 : ZEND_API void convert_to_null(zval *op) /* {{{ */
     489             : {
     490         914 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     491           3 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     492             :                         zval *org;
     493             :                         TSRMLS_FETCH();
     494             : 
     495           3 :                         ALLOC_ZVAL(org);
     496           3 :                         *org = *op;
     497           3 :                         if (Z_OBJ_HT_P(op)->cast_object(org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
     498             :                                 zval_dtor(org);
     499           0 :                                 return;
     500             :                         }
     501           3 :                         *op = *org;
     502           3 :                         FREE_ZVAL(org);
     503             :                 }
     504             :         }
     505             : 
     506             :         zval_dtor(op);
     507         914 :         Z_TYPE_P(op) = IS_NULL;
     508             : }
     509             : /* }}} */
     510             : 
     511       79706 : ZEND_API void convert_to_boolean(zval *op) /* {{{ */
     512             : {
     513             :         int tmp;
     514             : 
     515       79706 :         switch (Z_TYPE_P(op)) {
     516             :                 case IS_BOOL:
     517        3581 :                         break;
     518             :                 case IS_NULL:
     519         124 :                         Z_LVAL_P(op) = 0;
     520         124 :                         break;
     521             :                 case IS_RESOURCE: {
     522             :                                 TSRMLS_FETCH();
     523             : 
     524          36 :                                 zend_list_delete(Z_LVAL_P(op));
     525             :                         }
     526             :                         /* break missing intentionally */
     527             :                 case IS_LONG:
     528         834 :                         Z_LVAL_P(op) = (Z_LVAL_P(op) ? 1 : 0);
     529         834 :                         break;
     530             :                 case IS_DOUBLE:
     531         133 :                         Z_LVAL_P(op) = (Z_DVAL_P(op) ? 1 : 0);
     532         133 :                         break;
     533             :                 case IS_STRING:
     534             :                         {
     535         183 :                                 char *strval = Z_STRVAL_P(op);
     536             : 
     537         401 :                                 if (Z_STRLEN_P(op) == 0
     538         333 :                                         || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
     539          68 :                                         Z_LVAL_P(op) = 0;
     540             :                                 } else {
     541         115 :                                         Z_LVAL_P(op) = 1;
     542             :                                 }
     543         183 :                                 str_efree(strval);
     544             :                         }
     545         183 :                         break;
     546             :                 case IS_ARRAY:
     547          24 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     548             :                         zval_dtor(op);
     549          24 :                         Z_LVAL_P(op) = tmp;
     550          24 :                         break;
     551             :                 case IS_OBJECT:
     552             :                         {
     553       74827 :                                 zend_bool retval = 1;
     554             :                                 TSRMLS_FETCH();
     555             : 
     556      149653 :                                 convert_object_to_type(op, IS_BOOL, convert_to_boolean);
     557             : 
     558       74826 :                                 if (Z_TYPE_P(op) == IS_BOOL) {
     559       74826 :                                         return;
     560             :                                 }
     561             : 
     562             :                                 zval_dtor(op);
     563           0 :                                 ZVAL_BOOL(op, retval);
     564           0 :                                 break;
     565             :                         }
     566             :                 default:
     567             :                         zval_dtor(op);
     568           0 :                         Z_LVAL_P(op) = 0;
     569             :                         break;
     570             :         }
     571        4879 :         Z_TYPE_P(op) = IS_BOOL;
     572             : }
     573             : /* }}} */
     574             : 
     575          13 : ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     576             : {
     577             :         double dval;
     578          13 :         switch (Z_TYPE_P(op)) {
     579             :                 case IS_DOUBLE: {
     580             :                         TSRMLS_FETCH();
     581           1 :                         dval = Z_DVAL_P(op);
     582           1 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*H", (int) EG(precision), dval);
     583             :                         /* %H already handles removing trailing zeros from the fractional part, yay */
     584           1 :                         break;
     585             :                 }
     586             :                 default:
     587          12 :                         _convert_to_string(op ZEND_FILE_LINE_CC);
     588             :         }
     589          13 :         Z_TYPE_P(op) = IS_STRING;
     590          13 : }
     591             : /* }}} */
     592             : 
     593     1825901 : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     594             : {
     595             :         long lval;
     596             :         double dval;
     597             : 
     598     1825901 :         switch (Z_TYPE_P(op)) {
     599             :                 case IS_NULL:
     600        3969 :                         Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
     601        3969 :                         Z_STRLEN_P(op) = 0;
     602        3969 :                         break;
     603             :                 case IS_STRING:
     604           0 :                         break;
     605             :                 case IS_BOOL:
     606        2294 :                         if (Z_LVAL_P(op)) {
     607         868 :                                 Z_STRVAL_P(op) = estrndup_rel("1", 1);
     608         868 :                                 Z_STRLEN_P(op) = 1;
     609             :                         } else {
     610        1426 :                                 Z_STRVAL_P(op) = STR_EMPTY_ALLOC();
     611        1426 :                                 Z_STRLEN_P(op) = 0;
     612             :                         }
     613        2294 :                         break;
     614             :                 case IS_RESOURCE: {
     615          56 :                         long tmp = Z_LVAL_P(op);
     616             :                         TSRMLS_FETCH();
     617             : 
     618          56 :                         zend_list_delete(Z_LVAL_P(op));
     619          56 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "Resource id #%ld", tmp);
     620          56 :                         break;
     621             :                 }
     622             :                 case IS_LONG:
     623     1817112 :                         lval = Z_LVAL_P(op);
     624             : 
     625     1817112 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%ld", lval);
     626     1817112 :                         break;
     627             :                 case IS_DOUBLE: {
     628             :                         TSRMLS_FETCH();
     629        2142 :                         dval = Z_DVAL_P(op);
     630        2142 :                         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), dval);
     631             :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     632        2142 :                         break;
     633             :                 }
     634             :                 case IS_ARRAY:
     635         237 :                         zend_error(E_NOTICE, "Array to string conversion");
     636             :                         zval_dtor(op);
     637         237 :                         Z_STRVAL_P(op) = estrndup_rel("Array", sizeof("Array")-1);
     638         237 :                         Z_STRLEN_P(op) = sizeof("Array")-1;
     639         237 :                         break;
     640             :                 case IS_OBJECT: {
     641             :                         TSRMLS_FETCH();
     642             : 
     643         165 :                         convert_object_to_type(op, IS_STRING, convert_to_string);
     644             : 
     645          82 :                         if (Z_TYPE_P(op) == IS_STRING) {
     646          74 :                                 return;
     647             :                         }
     648             : 
     649           8 :                         zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name);
     650             :                         zval_dtor(op);
     651           8 :                         Z_STRVAL_P(op) = estrndup_rel("Object", sizeof("Object")-1);
     652           8 :                         Z_STRLEN_P(op) = sizeof("Object")-1;
     653           8 :                         break;
     654             :                 }
     655             :                 default:
     656             :                         zval_dtor(op);
     657           0 :                         ZVAL_BOOL(op, 0);
     658             :                         break;
     659             :         }
     660     1825818 :         Z_TYPE_P(op) = IS_STRING;
     661             : }
     662             : /* }}} */
     663             : 
     664         181 : static void convert_scalar_to_array(zval *op, int type TSRMLS_DC) /* {{{ */
     665             : {
     666             :         zval *entry;
     667             : 
     668         181 :         ALLOC_ZVAL(entry);
     669         181 :         *entry = *op;
     670         181 :         INIT_PZVAL(entry);
     671             : 
     672         181 :         switch (type) {
     673             :                 case IS_ARRAY:
     674         133 :                         ALLOC_HASHTABLE(Z_ARRVAL_P(op));
     675         133 :                         zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
     676         133 :                         zend_hash_index_update(Z_ARRVAL_P(op), 0, (void *) &entry, sizeof(zval *), NULL);
     677         133 :                         Z_TYPE_P(op) = IS_ARRAY;
     678         133 :                         break;
     679             :                 case IS_OBJECT:
     680          48 :                         object_init(op);
     681          48 :                         zend_hash_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar"), (void *) &entry, sizeof(zval *), NULL);
     682             :                         break;
     683             :         }
     684         181 : }
     685             : /* }}} */
     686             : 
     687       21336 : ZEND_API void convert_to_array(zval *op) /* {{{ */
     688             : {
     689             :         TSRMLS_FETCH();
     690             : 
     691       21336 :         switch (Z_TYPE_P(op)) {
     692             :                 case IS_ARRAY:
     693       21165 :                         break;
     694             : /* OBJECTS_OPTIMIZE */
     695             :                 case IS_OBJECT:
     696             :                         {
     697             :                                 zval *tmp;
     698             :                                 HashTable *ht;
     699             : 
     700          18 :                                 ALLOC_HASHTABLE(ht);
     701          18 :                                 zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     702          18 :                                 if (Z_OBJCE_P(op) == zend_ce_closure) {
     703           3 :                                         convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
     704           3 :                                         if (Z_TYPE_P(op) == IS_ARRAY) {
     705           3 :                                                 zend_hash_destroy(ht);
     706           3 :                                                 FREE_HASHTABLE(ht);
     707           3 :                                                 return;
     708             :                                         }
     709          15 :                                 } else if (Z_OBJ_HT_P(op)->get_properties) {
     710          15 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
     711          15 :                                         if (obj_ht) {
     712          15 :                                                 zend_hash_copy(ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     713             :                                         }
     714             :                                 } else {
     715           0 :                                         convert_object_to_type(op, IS_ARRAY, convert_to_array);
     716             : 
     717           0 :                                         if (Z_TYPE_P(op) == IS_ARRAY) {
     718           0 :                                                 zend_hash_destroy(ht);
     719           0 :                                                 FREE_HASHTABLE(ht);
     720           0 :                                                 return;
     721             :                                         }
     722             :                                 }
     723             :                                 zval_dtor(op);
     724          15 :                                 Z_TYPE_P(op) = IS_ARRAY;
     725          15 :                                 Z_ARRVAL_P(op) = ht;
     726             :                         }
     727          15 :                         break;
     728             :                 case IS_NULL:
     729          23 :                         ALLOC_HASHTABLE(Z_ARRVAL_P(op));
     730          23 :                         zend_hash_init(Z_ARRVAL_P(op), 0, NULL, ZVAL_PTR_DTOR, 0);
     731          23 :                         Z_TYPE_P(op) = IS_ARRAY;
     732          23 :                         break;
     733             :                 default:
     734         130 :                         convert_scalar_to_array(op, IS_ARRAY TSRMLS_CC);
     735             :                         break;
     736             :         }
     737             : }
     738             : /* }}} */
     739             : 
     740         128 : ZEND_API void convert_to_object(zval *op) /* {{{ */
     741             : {
     742             :         TSRMLS_FETCH();
     743             : 
     744         128 :         switch (Z_TYPE_P(op)) {
     745             :                 case IS_ARRAY:
     746             :                         {
     747          69 :                                 object_and_properties_init(op, zend_standard_class_def, Z_ARRVAL_P(op));
     748          69 :                                 break;
     749             :                         }
     750             :                 case IS_OBJECT:
     751           7 :                         break;
     752             :                 case IS_NULL:
     753           4 :                         object_init(op);
     754           4 :                         break;
     755             :                 default:
     756          48 :                         convert_scalar_to_array(op, IS_OBJECT TSRMLS_CC);
     757             :                         break;
     758             :         }
     759         128 : }
     760             : /* }}} */
     761             : 
     762           0 : ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
     763             : {
     764             :         zval **arg;
     765             :         va_list ap;
     766             : 
     767           0 :         va_start(ap, argc);
     768             : 
     769           0 :         while (argc--) {
     770           0 :                 arg = va_arg(ap, zval **);
     771           0 :                 convert_to_long_ex(arg);
     772             :         }
     773             : 
     774           0 :         va_end(ap);
     775           0 : }
     776             : /* }}} */
     777             : 
     778           0 : ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
     779             : {
     780             :         zval **arg;
     781             :         va_list ap;
     782             : 
     783           0 :         va_start(ap, argc);
     784             : 
     785           0 :         while (argc--) {
     786           0 :                 arg = va_arg(ap, zval **);
     787           0 :                 convert_to_double_ex(arg);
     788             :         }
     789             : 
     790           0 :         va_end(ap);
     791           0 : }
     792             : /* }}} */
     793             : 
     794           0 : ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
     795             : {
     796             :         zval **arg;
     797             :         va_list ap;
     798             : 
     799           0 :         va_start(ap, argc);
     800             : 
     801           0 :         while (argc--) {
     802           0 :                 arg = va_arg(ap, zval **);
     803           0 :                 convert_to_string_ex(arg);
     804             :         }
     805             : 
     806           0 :         va_end(ap);
     807           0 : }
     808             : /* }}} */
     809             : 
     810      814588 : ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     811             : {
     812             :         zval op1_copy, op2_copy;
     813      814588 :         int converted = 0;
     814             : 
     815             :         while (1) {
     816      815052 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     817             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     818      814283 :                                 long lval = Z_LVAL_P(op1) + Z_LVAL_P(op2);
     819             : 
     820             :                                 /* check for overflow by comparing sign bits */
     821     1628469 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     822     1628469 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     823             : 
     824           0 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
     825             :                                 } else {
     826      814283 :                                         ZVAL_LONG(result, lval);
     827             :                                 }
     828      814283 :                                 return SUCCESS;
     829             :                         }
     830             : 
     831             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     832         176 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     833         176 :                                 return SUCCESS;
     834             : 
     835             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     836          57 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     837          57 :                                 return SUCCESS;
     838             : 
     839             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     840          55 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     841          55 :                                 return SUCCESS;
     842             : 
     843             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY): {
     844             :                                 zval *tmp;
     845             : 
     846           8 :                                 if ((result == op1) && (result == op2)) {
     847             :                                         /* $a += $a */
     848           1 :                                         return SUCCESS;
     849             :                                 }
     850           7 :                                 if (result != op1) {
     851           6 :                                         *result = *op1;
     852             :                                         zval_copy_ctor(result);
     853             :                                 }
     854           7 :                                 zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), (void (*)(void *pData)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
     855           7 :                                 return SUCCESS;
     856             :                         }
     857             : 
     858             :                         default:
     859         473 :                                 if (!converted) {
     860         469 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD);
     861             : 
     862         465 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     863         465 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     864         464 :                                         converted = 1;
     865             :                                 } else {
     866           4 :                                         zend_error(E_ERROR, "Unsupported operand types");
     867           0 :                                         return FAILURE; /* unknown datatype */
     868             :                                 }
     869             :                 }
     870         464 :         }
     871             : }
     872             : /* }}} */
     873             : 
     874       63111 : ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     875             : {
     876             :         zval op1_copy, op2_copy;
     877       63111 :         int converted = 0;
     878             : 
     879             :         while (1) {
     880       63371 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     881             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     882       61299 :                                 long lval = Z_LVAL_P(op1) - Z_LVAL_P(op2);
     883             : 
     884             :                                 /* check for overflow by comparing sign bits */
     885       61317 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     886       61317 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     887             : 
     888           0 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
     889             :                                 } else {
     890       61299 :                                         ZVAL_LONG(result, lval);
     891             :                                 }
     892       61299 :                                 return SUCCESS;
     893             : 
     894             :                         }
     895             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     896        1703 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     897        1703 :                                 return SUCCESS;
     898             : 
     899             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     900          49 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     901          49 :                                 return SUCCESS;
     902             : 
     903             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     904          53 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     905          53 :                                 return SUCCESS;
     906             : 
     907             :                         default:
     908         267 :                                 if (!converted) {
     909         266 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB);
     910             : 
     911         261 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     912         260 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     913         260 :                                         converted = 1;
     914             :                                 } else {
     915           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     916           0 :                                         return FAILURE; /* unknown datatype */
     917             :                                 }
     918             :                 }
     919         260 :         }
     920             : }
     921             : /* }}} */
     922             : 
     923         302 : ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     924             : {
     925             :         zval op1_copy, op2_copy;
     926         302 :         int converted = 0;
     927             : 
     928             :         while (1) {
     929         528 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     930             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     931             :                                 long overflow;
     932             : 
     933         173 :                                 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
     934         173 :                                 Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG;
     935         173 :                                 return SUCCESS;
     936             : 
     937             :                         }
     938             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     939          45 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
     940          45 :                                 return SUCCESS;
     941             : 
     942             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     943          58 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
     944          58 :                                 return SUCCESS;
     945             : 
     946             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     947          25 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
     948          25 :                                 return SUCCESS;
     949             : 
     950             :                         default:
     951         227 :                                 if (!converted) {
     952         226 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL);
     953             : 
     954         226 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     955         226 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     956         226 :                                         converted = 1;
     957             :                                 } else {
     958           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     959           0 :                                         return FAILURE; /* unknown datatype */
     960             :                                 }
     961             :                 }
     962         226 :         }
     963             : }
     964             : /* }}} */
     965             : 
     966        2225 : ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     967             : {
     968             :         zval op1_copy, op2_copy;
     969        2225 :         int converted = 0;
     970             : 
     971             :         while (1) {
     972        2294 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     973             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
     974        1512 :                                 if (Z_LVAL_P(op2) >= 0) {
     975         829 :                                         long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
     976             : 
     977         829 :                                         if (i == 0) {
     978          26 :                                                 ZVAL_LONG(result, 1L);
     979          26 :                                                 return SUCCESS;
     980         803 :                                         } else if (l2 == 0) {
     981          14 :                                                 ZVAL_LONG(result, 0);
     982          14 :                                                 return SUCCESS;
     983             :                                         }
     984             : 
     985        6638 :                                         while (i >= 1) {
     986             :                                                 long overflow;
     987        5150 :                                                 double dval = 0.0;
     988             : 
     989        5150 :                                                 if (i % 2) {
     990        1998 :                                                         --i;
     991        1998 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
     992        1998 :                                                         if (overflow) {
     993          17 :                                                                 ZVAL_DOUBLE(result, dval * pow(l2, i));
     994          17 :                                                                 return SUCCESS;
     995             :                                                         }
     996             :                                                 } else {
     997        3152 :                                                         i /= 2;
     998        3152 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
     999        3152 :                                                         if (overflow) {
    1000          73 :                                                                 ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
    1001          73 :                                                                 return SUCCESS;
    1002             :                                                         }
    1003             :                                                 }
    1004             :                                         }
    1005             :                                         /* i == 0 */
    1006         699 :                                         ZVAL_LONG(result, l1);
    1007             :                                 } else {
    1008         683 :                                         ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
    1009             :                                 }
    1010        1382 :                                 return SUCCESS;
    1011             : 
    1012             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1013         501 :                                 ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
    1014         501 :                                 return SUCCESS;
    1015             : 
    1016             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1017         144 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
    1018         144 :                                 return SUCCESS;
    1019             : 
    1020             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1021          65 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
    1022          65 :                                 return SUCCESS;
    1023             : 
    1024             :                         default:
    1025          72 :                                 if (!converted) {
    1026          72 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW);
    1027             : 
    1028          71 :                                         if (Z_TYPE_P(op1) == IS_ARRAY) {
    1029           1 :                                                 ZVAL_LONG(result, 0);
    1030           1 :                                                 return SUCCESS;
    1031             :                                         } else {
    1032          71 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1033             :                                         }
    1034          70 :                                         if (Z_TYPE_P(op2) == IS_ARRAY) {
    1035           1 :                                                 ZVAL_LONG(result, 1L);
    1036           1 :                                                 return SUCCESS;
    1037             :                                         } else {
    1038          70 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1039             :                                         }
    1040          69 :                                         converted = 1;
    1041             :                                 } else {
    1042           0 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1043           0 :                                         return FAILURE;
    1044             :                                 }
    1045             :                 }
    1046          69 :         }
    1047             : }
    1048             : /* }}} */
    1049             : 
    1050      134650 : ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1051             : {
    1052             :         zval op1_copy, op2_copy;
    1053      134650 :         int converted = 0;
    1054             : 
    1055             :         while (1) {
    1056      134878 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1057             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1058      125136 :                                 if (Z_LVAL_P(op2) == 0) {
    1059          43 :                                         zend_error(E_WARNING, "Division by zero");
    1060          43 :                                         ZVAL_BOOL(result, 0);
    1061          43 :                                         return FAILURE;                 /* division by zero */
    1062      125093 :                                 } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
    1063             :                                         /* Prevent overflow error/crash */
    1064           1 :                                         ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
    1065           1 :                                         return SUCCESS;
    1066             :                                 }
    1067      125092 :                                 if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
    1068       80455 :                                         ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
    1069             :                                 } else {
    1070       44637 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
    1071             :                                 }
    1072      125092 :                                 return SUCCESS;
    1073             : 
    1074             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1075        9298 :                                 if (Z_LVAL_P(op2) == 0) {
    1076          17 :                                         zend_error(E_WARNING, "Division by zero");
    1077          17 :                                         ZVAL_BOOL(result, 0);
    1078          17 :                                         return FAILURE;                 /* division by zero */
    1079             :                                 }
    1080        9281 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
    1081        9281 :                                 return SUCCESS;
    1082             : 
    1083             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1084          68 :                                 if (Z_DVAL_P(op2) == 0) {
    1085           0 :                                         zend_error(E_WARNING, "Division by zero");
    1086           0 :                                         ZVAL_BOOL(result, 0);
    1087           0 :                                         return FAILURE;                 /* division by zero */
    1088             :                                 }
    1089          68 :                                 ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
    1090          68 :                                 return SUCCESS;
    1091             : 
    1092             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1093         143 :                                 if (Z_DVAL_P(op2) == 0) {
    1094           0 :                                         zend_error(E_WARNING, "Division by zero");
    1095           0 :                                         ZVAL_BOOL(result, 0);
    1096           0 :                                         return FAILURE;                 /* division by zero */
    1097             :                                 }
    1098         143 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
    1099         143 :                                 return SUCCESS;
    1100             : 
    1101             :                         default:
    1102         233 :                                 if (!converted) {
    1103         232 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV);
    1104             : 
    1105         228 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1106         228 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1107         228 :                                         converted = 1;
    1108             :                                 } else {
    1109           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1110           0 :                                         return FAILURE; /* unknown datatype */
    1111             :                                 }
    1112             :                 }
    1113         228 :         }
    1114             : }
    1115             : /* }}} */
    1116             : 
    1117         386 : ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1118             : {
    1119             :         zval op1_copy, op2_copy;
    1120             :         long op1_lval;
    1121             : 
    1122         768 :         if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
    1123         386 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MOD);
    1124             : 
    1125         503 :                 zendi_convert_to_long(op1, op1_copy, result);
    1126         382 :                 op1_lval = Z_LVAL_P(op1);
    1127         502 :                 zendi_convert_to_long(op2, op2_copy, result);
    1128             :         } else {
    1129           0 :                 op1_lval = Z_LVAL_P(op1);
    1130             :         }
    1131             : 
    1132         382 :         if (Z_LVAL_P(op2) == 0) {
    1133          45 :                 zend_error(E_WARNING, "Division by zero");
    1134          45 :                 ZVAL_BOOL(result, 0);
    1135          45 :                 return FAILURE;                 /* modulus by zero */
    1136             :         }
    1137             : 
    1138         337 :         if (Z_LVAL_P(op2) == -1) {
    1139             :                 /* Prevent overflow error/crash if op1==LONG_MIN */
    1140           2 :                 ZVAL_LONG(result, 0);
    1141           2 :                 return SUCCESS;
    1142             :         }
    1143             : 
    1144         335 :         ZVAL_LONG(result, op1_lval % Z_LVAL_P(op2));
    1145         335 :         return SUCCESS;
    1146             : }
    1147             : /* }}} */
    1148             : 
    1149           2 : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1150             : {
    1151             :         zval op1_copy, op2_copy;
    1152             :         long op1_lval;
    1153             : 
    1154           4 :         if (Z_TYPE_P(op1) != IS_BOOL || Z_TYPE_P(op2) != IS_BOOL) {
    1155           2 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BOOL_XOR);
    1156             : 
    1157           2 :                 zendi_convert_to_boolean(op1, op1_copy, result);
    1158           2 :                 op1_lval = Z_LVAL_P(op1);
    1159           2 :                 zendi_convert_to_boolean(op2, op2_copy, result);
    1160             :         } else {
    1161           0 :                 op1_lval = Z_LVAL_P(op1);
    1162             :         }
    1163             : 
    1164           2 :         ZVAL_BOOL(result, op1_lval ^ Z_LVAL_P(op2));
    1165           2 :         return SUCCESS;
    1166             : }
    1167             : /* }}} */
    1168             : 
    1169     3036749 : ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1170             : {
    1171             :         zval op1_copy;
    1172             : 
    1173     3036749 :         if (Z_TYPE_P(op1) != IS_BOOL) {
    1174      274839 :                 ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
    1175             : 
    1176      349644 :                 zendi_convert_to_boolean(op1, op1_copy, result);
    1177             :         }
    1178             : 
    1179     3036749 :         ZVAL_BOOL(result, !Z_LVAL_P(op1));
    1180     3036749 :         return SUCCESS;
    1181             : }
    1182             : /* }}} */
    1183             : 
    1184         149 : ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1185             : {
    1186             : 
    1187         149 :         switch (Z_TYPE_P(op1)) {
    1188             :                 case IS_LONG:
    1189         129 :                         ZVAL_LONG(result, ~Z_LVAL_P(op1));
    1190         129 :                         return SUCCESS;
    1191             :                 case IS_DOUBLE:
    1192           6 :                         ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
    1193           3 :                         return SUCCESS;
    1194             :                 case IS_STRING: {
    1195             :                         int i;
    1196          15 :                         zval op1_copy = *op1;
    1197             : 
    1198          15 :                         Z_TYPE_P(result) = IS_STRING;
    1199          15 :                         Z_STRVAL_P(result) = estrndup(Z_STRVAL(op1_copy), Z_STRLEN(op1_copy));
    1200          15 :                         Z_STRLEN_P(result) = Z_STRLEN(op1_copy);
    1201          83 :                         for (i = 0; i < Z_STRLEN(op1_copy); i++) {
    1202          68 :                                 Z_STRVAL_P(result)[i] = ~Z_STRVAL(op1_copy)[i];
    1203             :                         }
    1204          15 :                         return SUCCESS;
    1205             :                 }
    1206             :                 default:
    1207           2 :                         ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
    1208             : 
    1209           1 :                         zend_error(E_ERROR, "Unsupported operand types");
    1210           0 :                         return FAILURE;
    1211             :         }
    1212             : }
    1213             : /* }}} */
    1214             : 
    1215      578061 : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1216             : {
    1217             :         zval op1_copy, op2_copy;
    1218             :         long op1_lval;
    1219             : 
    1220      578061 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1221             :                 zval *longer, *shorter;
    1222             :                 char *result_str;
    1223             :                 int i, result_len;
    1224             : 
    1225         200 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1226         117 :                         longer = op1;
    1227         117 :                         shorter = op2;
    1228             :                 } else {
    1229          83 :                         longer = op2;
    1230          83 :                         shorter = op1;
    1231             :                 }
    1232             : 
    1233         200 :                 Z_TYPE_P(result) = IS_STRING;
    1234         200 :                 result_len = Z_STRLEN_P(longer);
    1235         200 :                 result_str = estrndup(Z_STRVAL_P(longer), Z_STRLEN_P(longer));
    1236         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1237         688 :                         result_str[i] |= Z_STRVAL_P(shorter)[i];
    1238             :                 }
    1239         200 :                 if (result==op1) {
    1240           1 :                         str_efree(Z_STRVAL_P(result));
    1241             :                 }
    1242         200 :                 Z_STRVAL_P(result) = result_str;
    1243         200 :                 Z_STRLEN_P(result) = result_len;
    1244         200 :                 return SUCCESS;
    1245             :         }
    1246             : 
    1247      577897 :         if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
    1248          39 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_OR);
    1249             : 
    1250          54 :                 zendi_convert_to_long(op1, op1_copy, result);
    1251          36 :                 op1_lval = Z_LVAL_P(op1);
    1252          54 :                 zendi_convert_to_long(op2, op2_copy, result);
    1253             :         } else {
    1254      577822 :                 op1_lval = Z_LVAL_P(op1);
    1255             :         }
    1256             : 
    1257      577858 :         ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
    1258      577858 :         return SUCCESS;
    1259             : }
    1260             : /* }}} */
    1261             : 
    1262      359539 : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1263             : {
    1264             :         zval op1_copy, op2_copy;
    1265             :         long op1_lval;
    1266             : 
    1267      359539 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1268             :                 zval *longer, *shorter;
    1269             :                 char *result_str;
    1270             :                 int i, result_len;
    1271             : 
    1272         201 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1273         117 :                         longer = op1;
    1274         117 :                         shorter = op2;
    1275             :                 } else {
    1276          84 :                         longer = op2;
    1277          84 :                         shorter = op1;
    1278             :                 }
    1279             : 
    1280         201 :                 Z_TYPE_P(result) = IS_STRING;
    1281         201 :                 result_len = Z_STRLEN_P(shorter);
    1282         201 :                 result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
    1283         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1284         687 :                         result_str[i] &= Z_STRVAL_P(longer)[i];
    1285             :                 }
    1286         201 :                 if (result==op1) {
    1287           1 :                         str_efree(Z_STRVAL_P(result));
    1288             :                 }
    1289         201 :                 Z_STRVAL_P(result) = result_str;
    1290         201 :                 Z_STRLEN_P(result) = result_len;
    1291         201 :                 return SUCCESS;
    1292             :         }
    1293             : 
    1294      359387 :         if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
    1295          52 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_AND);
    1296             : 
    1297          67 :                 zendi_convert_to_long(op1, op1_copy, result);
    1298          49 :                 op1_lval = Z_LVAL_P(op1);
    1299          67 :                 zendi_convert_to_long(op2, op2_copy, result);
    1300             :         } else {
    1301      359286 :                 op1_lval = Z_LVAL_P(op1);
    1302             :         }
    1303             : 
    1304      359335 :         ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
    1305      359335 :         return SUCCESS;
    1306             : }
    1307             : /* }}} */
    1308             : 
    1309         488 : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1310             : {
    1311             :         zval op1_copy, op2_copy;
    1312             :         long op1_lval;
    1313             : 
    1314         488 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1315             :                 zval *longer, *shorter;
    1316             :                 char *result_str;
    1317             :                 int i, result_len;
    1318             : 
    1319         202 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1320         118 :                         longer = op1;
    1321         118 :                         shorter = op2;
    1322             :                 } else {
    1323          84 :                         longer = op2;
    1324          84 :                         shorter = op1;
    1325             :                 }
    1326             : 
    1327         202 :                 Z_TYPE_P(result) = IS_STRING;
    1328         202 :                 result_len = Z_STRLEN_P(shorter);
    1329         202 :                 result_str = estrndup(Z_STRVAL_P(shorter), Z_STRLEN_P(shorter));
    1330         892 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1331         690 :                         result_str[i] ^= Z_STRVAL_P(longer)[i];
    1332             :                 }
    1333         202 :                 if (result==op1) {
    1334           1 :                         str_efree(Z_STRVAL_P(result));
    1335             :                 }
    1336         202 :                 Z_STRVAL_P(result) = result_str;
    1337         202 :                 Z_STRLEN_P(result) = result_len;
    1338         202 :                 return SUCCESS;
    1339             :         }
    1340             : 
    1341         326 :         if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
    1342          43 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_BW_XOR);
    1343             : 
    1344          58 :                 zendi_convert_to_long(op1, op1_copy, result);
    1345          40 :                 op1_lval = Z_LVAL_P(op1);
    1346          58 :                 zendi_convert_to_long(op2, op2_copy, result);
    1347             :         } else {
    1348         243 :                 op1_lval = Z_LVAL_P(op1);
    1349             :         }
    1350             : 
    1351         283 :         ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
    1352         283 :         return SUCCESS;
    1353             : }
    1354             : /* }}} */
    1355             : 
    1356        3433 : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1357             : {
    1358             :         zval op1_copy, op2_copy;
    1359             :         long op1_lval;
    1360             : 
    1361        3671 :         if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
    1362         241 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SL);
    1363             : 
    1364         256 :                 zendi_convert_to_long(op1, op1_copy, result);
    1365         238 :                 op1_lval = Z_LVAL_P(op1);
    1366         256 :                 zendi_convert_to_long(op2, op2_copy, result);
    1367             :         } else {
    1368        3192 :                 op1_lval = Z_LVAL_P(op1);
    1369             :         }
    1370             : 
    1371        3430 :         ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2));
    1372        3430 :         return SUCCESS;
    1373             : }
    1374             : /* }}} */
    1375             : 
    1376      350245 : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1377             : {
    1378             :         zval op1_copy, op2_copy;
    1379             :         long op1_lval;
    1380             : 
    1381      350483 :         if (Z_TYPE_P(op1) != IS_LONG || Z_TYPE_P(op2) != IS_LONG) {
    1382         240 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SR);
    1383             : 
    1384         256 :                 zendi_convert_to_long(op1, op1_copy, result);
    1385         238 :                 op1_lval = Z_LVAL_P(op1);
    1386         256 :                 zendi_convert_to_long(op2, op2_copy, result);
    1387             :         } else {
    1388      350005 :                 op1_lval = Z_LVAL_P(op1);
    1389             :         }
    1390             : 
    1391      350243 :         ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2));
    1392      350243 :         return SUCCESS;
    1393             : }
    1394             : /* }}} */
    1395             : 
    1396             : /* must support result==op1 */
    1397     1124059 : ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1398             : {
    1399     1124059 :         int length = Z_STRLEN_P(op1) + 1;
    1400     1124059 :         char *buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
    1401             : 
    1402     1124059 :         buf[length - 1] = (char) Z_LVAL_P(op2);
    1403     1124059 :         buf[length] = 0;
    1404     1124059 :         ZVAL_STRINGL(result, buf, length, 0);
    1405     1124059 :         return SUCCESS;
    1406             : }
    1407             : /* }}} */
    1408             : 
    1409             : /* must support result==op1 */
    1410     3098483 : ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1411             : {
    1412     3098483 :         int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1413     3098483 :         char *buf = str_erealloc(Z_STRVAL_P(op1), length + 1);
    1414             : 
    1415     3098483 :         memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1416     3098483 :         buf[length] = 0;
    1417     3098483 :         ZVAL_STRINGL(result, buf, length, 0);
    1418     3098483 :         return SUCCESS;
    1419             : }
    1420             : /* }}} */
    1421             : 
    1422     4498681 : ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1423             : {
    1424             :         zval op1_copy, op2_copy;
    1425     4498681 :         int use_copy1 = 0, use_copy2 = 0;
    1426             : 
    1427     4498681 :         if (Z_TYPE_P(op1) != IS_STRING || Z_TYPE_P(op2) != IS_STRING) {
    1428       73797 :                 ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT);
    1429             : 
    1430       73797 :                 if (Z_TYPE_P(op1) != IS_STRING) {
    1431       31788 :                         zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1432             :                 }
    1433       73797 :                 if (Z_TYPE_P(op2) != IS_STRING) {
    1434       42356 :                         zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1435             :                 }
    1436             :         }
    1437             : 
    1438     4498681 :         if (use_copy1) {
    1439             :                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1440             :                  * we have to free it.
    1441             :                  */
    1442       31788 :                 if (result == op1) {
    1443             :                         zval_dtor(op1);
    1444             :                 }
    1445       31788 :                 op1 = &op1_copy;
    1446             :         }
    1447     4498681 :         if (use_copy2) {
    1448       42356 :                 op2 = &op2_copy;
    1449             :         }
    1450     7790811 :         if (result==op1 && !IS_INTERNED(Z_STRVAL_P(op1))) {     /* special case, perform operations on result */
    1451     3292130 :                 uint res_len = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1452             : 
    1453     3292130 :                 if (Z_STRLEN_P(result) < 0 || (int) (Z_STRLEN_P(op1) + Z_STRLEN_P(op2)) < 0) {
    1454           0 :                         efree(Z_STRVAL_P(result));
    1455           0 :                         ZVAL_EMPTY_STRING(result);
    1456           0 :                         zend_error(E_ERROR, "String size overflow");
    1457             :                 }
    1458             : 
    1459     3292130 :                 Z_STRVAL_P(result) = erealloc(Z_STRVAL_P(result), res_len+1);
    1460             : 
    1461     3292130 :                 memcpy(Z_STRVAL_P(result)+Z_STRLEN_P(result), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1462     3292130 :                 Z_STRVAL_P(result)[res_len]=0;
    1463     3292130 :                 Z_STRLEN_P(result) = res_len;
    1464             :         } else {
    1465     1206551 :                 int length = Z_STRLEN_P(op1) + Z_STRLEN_P(op2);
    1466     1206551 :                 char *buf = (char *) emalloc(length + 1);
    1467             : 
    1468     1206551 :                 memcpy(buf, Z_STRVAL_P(op1), Z_STRLEN_P(op1));
    1469     1206551 :                 memcpy(buf + Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1470     1206551 :                 buf[length] = 0;
    1471     1206551 :                 ZVAL_STRINGL(result, buf, length, 0);
    1472             :         }
    1473     4498681 :         if (use_copy1) {
    1474             :                 zval_dtor(op1);
    1475             :         }
    1476     4498681 :         if (use_copy2) {
    1477             :                 zval_dtor(op2);
    1478             :         }
    1479     4498681 :         return SUCCESS;
    1480             : }
    1481             : /* }}} */
    1482             : 
    1483      314004 : ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */
    1484             : {
    1485             :         zval op1_copy, op2_copy;
    1486      314004 :         int use_copy1 = 0, use_copy2 = 0;
    1487             : 
    1488      314004 :         if (Z_TYPE_P(op1) != IS_STRING) {
    1489       77359 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1490             :         }
    1491      314004 :         if (Z_TYPE_P(op2) != IS_STRING) {
    1492       79724 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1493             :         }
    1494             : 
    1495      314004 :         if (use_copy1) {
    1496       77359 :                 op1 = &op1_copy;
    1497             :         }
    1498      314004 :         if (use_copy2) {
    1499       79724 :                 op2 = &op2_copy;
    1500             :         }
    1501             : 
    1502      314004 :         if (case_insensitive) {
    1503         109 :                 ZVAL_LONG(result, zend_binary_zval_strcasecmp(op1, op2));
    1504             :         } else {
    1505      313895 :                 ZVAL_LONG(result, zend_binary_zval_strcmp(op1, op2));
    1506             :         }
    1507             : 
    1508      314004 :         if (use_copy1) {
    1509             :                 zval_dtor(op1);
    1510             :         }
    1511      314004 :         if (use_copy2) {
    1512             :                 zval_dtor(op2);
    1513             :         }
    1514      314004 :         return SUCCESS;
    1515             : }
    1516             : /* }}} */
    1517             : 
    1518      313895 : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1519             : {
    1520      313895 :         return string_compare_function_ex(result, op1, op2, 0 TSRMLS_CC);
    1521             : }
    1522             : /* }}} */
    1523             : 
    1524         109 : ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1525             : {
    1526         109 :         return string_compare_function_ex(result, op1, op2, 1 TSRMLS_CC);
    1527             : }
    1528             : /* }}} */
    1529             : 
    1530             : #if HAVE_STRCOLL
    1531          33 : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1532             : {
    1533             :         zval op1_copy, op2_copy;
    1534          33 :         int use_copy1 = 0, use_copy2 = 0;
    1535             : 
    1536          33 :         if (Z_TYPE_P(op1) != IS_STRING) {
    1537           0 :                 zend_make_printable_zval(op1, &op1_copy, &use_copy1);
    1538             :         }
    1539          33 :         if (Z_TYPE_P(op2) != IS_STRING) {
    1540           0 :                 zend_make_printable_zval(op2, &op2_copy, &use_copy2);
    1541             :         }
    1542             : 
    1543          33 :         if (use_copy1) {
    1544           0 :                 op1 = &op1_copy;
    1545             :         }
    1546          33 :         if (use_copy2) {
    1547           0 :                 op2 = &op2_copy;
    1548             :         }
    1549             : 
    1550          33 :         ZVAL_LONG(result, strcoll(Z_STRVAL_P(op1), Z_STRVAL_P(op2)));
    1551             : 
    1552          33 :         if (use_copy1) {
    1553             :                 zval_dtor(op1);
    1554             :         }
    1555          33 :         if (use_copy2) {
    1556             :                 zval_dtor(op2);
    1557             :         }
    1558          33 :         return SUCCESS;
    1559             : }
    1560             : /* }}} */
    1561             : #endif
    1562             : 
    1563         844 : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1564             : {
    1565             :         zval op1_copy, op2_copy;
    1566             : 
    1567         844 :         op1_copy = *op1;
    1568             :         zval_copy_ctor(&op1_copy);
    1569             : 
    1570         844 :         op2_copy = *op2;
    1571             :         zval_copy_ctor(&op2_copy);
    1572             : 
    1573         844 :         convert_to_double(&op1_copy);
    1574         844 :         convert_to_double(&op2_copy);
    1575             : 
    1576         844 :         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL(op1_copy)-Z_DVAL(op2_copy)));
    1577             : 
    1578         844 :         return SUCCESS;
    1579             : }
    1580             : /* }}} */
    1581             : 
    1582         413 : static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
    1583             : {
    1584         826 :         if (Z_REFCOUNT_P(op) == 0) {
    1585           1 :                 GC_REMOVE_ZVAL_FROM_BUFFER(op);
    1586           1 :                 zval_dtor(op);
    1587           1 :                 FREE_ZVAL(op);
    1588             :         } else {
    1589         412 :                 zval_ptr_dtor(&op);
    1590             :         }
    1591         413 : }
    1592             : /* }}} */
    1593             : 
    1594     2533229 : ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1595             : {
    1596             :         int ret;
    1597     2533229 :         int converted = 0;
    1598             :         zval op1_copy, op2_copy;
    1599             :         zval *op_free;
    1600             : 
    1601             :         while (1) {
    1602     2559530 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1603             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1604       46108 :                                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1605       46108 :                                 return SUCCESS;
    1606             : 
    1607             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1608         642 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
    1609         642 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1610         642 :                                 return SUCCESS;
    1611             : 
    1612             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1613         295 :                                 Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
    1614         295 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1615         295 :                                 return SUCCESS;
    1616             : 
    1617             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1618         388 :                                 if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
    1619          99 :                                         ZVAL_LONG(result, 0);
    1620             :                                 } else {
    1621         289 :                                         Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    1622         289 :                                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1623             :                                 }
    1624         388 :                                 return SUCCESS;
    1625             : 
    1626             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
    1627         791 :                                 zend_compare_arrays(result, op1, op2 TSRMLS_CC);
    1628         791 :                                 return SUCCESS;
    1629             : 
    1630             :                         case TYPE_PAIR(IS_NULL, IS_NULL):
    1631         308 :                                 ZVAL_LONG(result, 0);
    1632         308 :                                 return SUCCESS;
    1633             : 
    1634             :                         case TYPE_PAIR(IS_NULL, IS_BOOL):
    1635          37 :                                 ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
    1636          37 :                                 return SUCCESS;
    1637             : 
    1638             :                         case TYPE_PAIR(IS_BOOL, IS_NULL):
    1639          30 :                                 ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
    1640          30 :                                 return SUCCESS;
    1641             : 
    1642             :                         case TYPE_PAIR(IS_BOOL, IS_BOOL):
    1643        4828 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1644        4828 :                                 return SUCCESS;
    1645             : 
    1646             :                         case TYPE_PAIR(IS_STRING, IS_STRING):
    1647     2112800 :                                 zendi_smart_strcmp(result, op1, op2);
    1648     2112800 :                                 return SUCCESS;
    1649             : 
    1650             :                         case TYPE_PAIR(IS_NULL, IS_STRING):
    1651       12504 :                                 ZVAL_LONG(result, zend_binary_strcmp("", 0, Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1652       12504 :                                 return SUCCESS;
    1653             : 
    1654             :                         case TYPE_PAIR(IS_STRING, IS_NULL):
    1655         139 :                                 ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), "", 0));
    1656         139 :                                 return SUCCESS;
    1657             : 
    1658             :                         case TYPE_PAIR(IS_OBJECT, IS_NULL):
    1659          49 :                                 ZVAL_LONG(result, 1);
    1660          49 :                                 return SUCCESS;
    1661             : 
    1662             :                         case TYPE_PAIR(IS_NULL, IS_OBJECT):
    1663          15 :                                 ZVAL_LONG(result, -1);
    1664          15 :                                 return SUCCESS;
    1665             : 
    1666             :                         default:
    1667      380596 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
    1668          17 :                                         return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2 TSRMLS_CC);
    1669      380579 :                                 } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
    1670           6 :                                         return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2 TSRMLS_CC);
    1671             :                                 }
    1672             : 
    1673      380573 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
    1674      346901 :                                         if (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2)) {
    1675             :                                                 /* object handles are identical, apparently this is the same object */
    1676          24 :                                                 ZVAL_LONG(result, 0);
    1677          24 :                                                 return SUCCESS;
    1678             :                                         }
    1679      346877 :                                         if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
    1680      346876 :                                                 ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2 TSRMLS_CC));
    1681      346872 :                                                 return SUCCESS;
    1682             :                                         }
    1683             :                                 }
    1684       33673 :                                 if (Z_TYPE_P(op1) == IS_OBJECT) {
    1685         217 :                                         if (Z_OBJ_HT_P(op1)->get) {
    1686           1 :                                                 op_free = Z_OBJ_HT_P(op1)->get(op1 TSRMLS_CC);
    1687           1 :                                                 ret = compare_function(result, op_free, op2 TSRMLS_CC);
    1688           1 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1689           1 :                                                 return ret;
    1690         216 :                                         } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
    1691         215 :                                                 ALLOC_INIT_ZVAL(op_free);
    1692         215 :                                                 if (Z_OBJ_HT_P(op1)->cast_object(op1, op_free, Z_TYPE_P(op2) TSRMLS_CC) == FAILURE) {
    1693         112 :                                                         ZVAL_LONG(result, 1);
    1694         112 :                                                         zend_free_obj_get_result(op_free TSRMLS_CC);
    1695         112 :                                                         return SUCCESS;
    1696             :                                                 }
    1697         103 :                                                 ret = compare_function(result, op_free, op2 TSRMLS_CC);
    1698         103 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1699         103 :                                                 return ret;
    1700             :                                         }
    1701             :                                 }
    1702       33457 :                                 if (Z_TYPE_P(op2) == IS_OBJECT) {
    1703         198 :                                         if (Z_OBJ_HT_P(op2)->get) {
    1704           0 :                                                 op_free = Z_OBJ_HT_P(op2)->get(op2 TSRMLS_CC);
    1705           0 :                                                 ret = compare_function(result, op1, op_free TSRMLS_CC);
    1706           0 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1707           0 :                                                 return ret;
    1708         198 :                                         } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
    1709         197 :                                                 ALLOC_INIT_ZVAL(op_free);
    1710         197 :                                                 if (Z_OBJ_HT_P(op2)->cast_object(op2, op_free, Z_TYPE_P(op1) TSRMLS_CC) == FAILURE) {
    1711         107 :                                                         ZVAL_LONG(result, -1);
    1712         107 :                                                         zend_free_obj_get_result(op_free TSRMLS_CC);
    1713         107 :                                                         return SUCCESS;
    1714             :                                                 }
    1715          90 :                                                 ret = compare_function(result, op1, op_free TSRMLS_CC);
    1716          90 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1717          90 :                                                 return ret;
    1718           1 :                                         } else if (Z_TYPE_P(op1) == IS_OBJECT) {
    1719           1 :                                                 ZVAL_LONG(result, 1);
    1720           1 :                                                 return SUCCESS;
    1721             :                                         }
    1722             :                                 }
    1723       33259 :                                 if (!converted) {
    1724       32699 :                                         if (Z_TYPE_P(op1) == IS_NULL) {
    1725         209 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1726         209 :                                                 ZVAL_LONG(result, Z_LVAL_P(op2) ? -1 : 0);
    1727         209 :                                                 return SUCCESS;
    1728       32490 :                                         } else if (Z_TYPE_P(op2) == IS_NULL) {
    1729          90 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1730          90 :                                                 ZVAL_LONG(result, Z_LVAL_P(op1) ? 1 : 0);
    1731          90 :                                                 return SUCCESS;
    1732       32400 :                                         } else if (Z_TYPE_P(op1) == IS_BOOL) {
    1733        2632 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1734        2632 :                                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1735        2632 :                                                 return SUCCESS;
    1736       29768 :                                         } else if (Z_TYPE_P(op2) == IS_BOOL) {
    1737        3467 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1738        3467 :                                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(op1) - Z_LVAL_P(op2)));
    1739        3467 :                                                 return SUCCESS;
    1740             :                                         } else {
    1741       26301 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1742       26301 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1743       26301 :                                                 converted = 1;
    1744             :                                         }
    1745         560 :                                 } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    1746         276 :                                         ZVAL_LONG(result, 1);
    1747         276 :                                         return SUCCESS;
    1748         284 :                                 } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    1749         284 :                                         ZVAL_LONG(result, -1);
    1750         284 :                                         return SUCCESS;
    1751           0 :                                 } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    1752           0 :                                         ZVAL_LONG(result, 1);
    1753           0 :                                         return SUCCESS;
    1754           0 :                                 } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    1755           0 :                                         ZVAL_LONG(result, -1);
    1756           0 :                                         return SUCCESS;
    1757             :                                 } else {
    1758           0 :                                         ZVAL_LONG(result, 0);
    1759           0 :                                         return FAILURE;
    1760             :                                 }
    1761             :                 }
    1762       26301 :         }
    1763             : }
    1764             : /* }}} */
    1765             : 
    1766        1128 : static int hash_zval_identical_function(const zval **z1, const zval **z2) /* {{{ */
    1767             : {
    1768             :         zval result;
    1769             :         TSRMLS_FETCH();
    1770             : 
    1771             :         /* is_identical_function() returns 1 in case of identity and 0 in case
    1772             :          * of a difference;
    1773             :          * whereas this comparison function is expected to return 0 on identity,
    1774             :          * and non zero otherwise.
    1775             :          */
    1776        1128 :         if (is_identical_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    1777           0 :                 return 1;
    1778             :         }
    1779        1128 :         return !Z_LVAL(result);
    1780             : }
    1781             : /* }}} */
    1782             : 
    1783     4179975 : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1784             : {
    1785     4179975 :         Z_TYPE_P(result) = IS_BOOL;
    1786     4179975 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    1787     3069437 :                 Z_LVAL_P(result) = 0;
    1788     3069437 :                 return SUCCESS;
    1789             :         }
    1790     1110538 :         switch (Z_TYPE_P(op1)) {
    1791             :                 case IS_NULL:
    1792        2530 :                         Z_LVAL_P(result) = 1;
    1793        2530 :                         break;
    1794             :                 case IS_BOOL:
    1795             :                 case IS_LONG:
    1796             :                 case IS_RESOURCE:
    1797     1005908 :                         Z_LVAL_P(result) = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
    1798     1005908 :                         break;
    1799             :                 case IS_DOUBLE:
    1800         179 :                         Z_LVAL_P(result) = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
    1801         179 :                         break;
    1802             :                 case IS_STRING:
    1803       69231 :                         Z_LVAL_P(result) = ((Z_STRLEN_P(op1) == Z_STRLEN_P(op2))
    1804       33465 :                                 && (!memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1))));
    1805       35766 :                         break;
    1806             :                 case IS_ARRAY:
    1807         134 :                         Z_LVAL_P(result) = (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
    1808          66 :                                 zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1 TSRMLS_CC)==0);
    1809          68 :                         break;
    1810             :                 case IS_OBJECT:
    1811       66087 :                         if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
    1812       66087 :                                 Z_LVAL_P(result) = (Z_OBJ_HANDLE_P(op1) == Z_OBJ_HANDLE_P(op2));
    1813             :                         } else {
    1814           0 :                                 Z_LVAL_P(result) = 0;
    1815             :                         }
    1816       66087 :                         break;
    1817             :                 default:
    1818           0 :                         Z_LVAL_P(result) = 0;
    1819           0 :                         return FAILURE;
    1820             :         }
    1821     1110538 :         return SUCCESS;
    1822             : }
    1823             : /* }}} */
    1824             : 
    1825           1 : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1826             : {
    1827           1 :         if (is_identical_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1828           0 :                 return FAILURE;
    1829             :         }
    1830           1 :         Z_LVAL_P(result) = !Z_LVAL_P(result);
    1831           1 :         return SUCCESS;
    1832             : }
    1833             : /* }}} */
    1834             : 
    1835      510830 : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1836             : {
    1837      510830 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1838           0 :                 return FAILURE;
    1839             :         }
    1840      510830 :         ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
    1841      510830 :         return SUCCESS;
    1842             : }
    1843             : /* }}} */
    1844             : 
    1845           1 : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1846             : {
    1847           1 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1848           0 :                 return FAILURE;
    1849             :         }
    1850           1 :         ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
    1851           1 :         return SUCCESS;
    1852             : }
    1853             : /* }}} */
    1854             : 
    1855        1895 : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1856             : {
    1857        1895 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1858           0 :                 return FAILURE;
    1859             :         }
    1860        1895 :         ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
    1861        1895 :         return SUCCESS;
    1862             : }
    1863             : /* }}} */
    1864             : 
    1865        1285 : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1866             : {
    1867        1285 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    1868           0 :                 return FAILURE;
    1869             :         }
    1870        1285 :         ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
    1871        1285 :         return SUCCESS;
    1872             : }
    1873             : /* }}} */
    1874             : 
    1875     2317241 : ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC) /* {{{ */
    1876             : {
    1877             :         zend_uint i;
    1878             : 
    1879     3000728 :         for (i=0; i<instance_ce->num_interfaces; i++) {
    1880     1104917 :                 if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) {
    1881      421430 :                         return 1;
    1882             :                 }
    1883             :         }
    1884     1895811 :         if (!interfaces_only) {
    1885     4499110 :                 while (instance_ce) {
    1886     1906599 :                         if (instance_ce == ce) {
    1887     1199101 :                                 return 1;
    1888             :                         }
    1889      707498 :                         instance_ce = instance_ce->parent;
    1890             :                 }
    1891             :         }
    1892             : 
    1893      696710 :         return 0;
    1894             : }
    1895             : /* }}} */
    1896             : 
    1897     2250435 : ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC) /* {{{ */
    1898             : {
    1899     2250435 :         return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
    1900             : }
    1901             : /* }}} */
    1902             : 
    1903             : #define LOWER_CASE 1
    1904             : #define UPPER_CASE 2
    1905             : #define NUMERIC 3
    1906             : 
    1907          46 : static void increment_string(zval *str) /* {{{ */
    1908             : {
    1909          46 :         int carry=0;
    1910          46 :         int pos=Z_STRLEN_P(str)-1;
    1911          46 :         char *s=Z_STRVAL_P(str);
    1912             :         char *t;
    1913          46 :         int last=0; /* Shut up the compiler warning */
    1914             :         int ch;
    1915             : 
    1916          46 :         if (Z_STRLEN_P(str) == 0) {
    1917           0 :                 str_efree(Z_STRVAL_P(str));
    1918           0 :                 Z_STRVAL_P(str) = estrndup("1", sizeof("1")-1);
    1919           0 :                 Z_STRLEN_P(str) = 1;
    1920           0 :                 return;
    1921             :         }
    1922             : 
    1923          46 :         if (IS_INTERNED(s)) {
    1924          21 :                 Z_STRVAL_P(str) = s = estrndup(s, Z_STRLEN_P(str));
    1925             :         }
    1926             : 
    1927          96 :         while (pos >= 0) {
    1928          50 :                 ch = s[pos];
    1929          81 :                 if (ch >= 'a' && ch <= 'z') {
    1930          31 :                         if (ch == 'z') {
    1931           2 :                                 s[pos] = 'a';
    1932           2 :                                 carry=1;
    1933             :                         } else {
    1934          29 :                                 s[pos]++;
    1935          29 :                                 carry=0;
    1936             :                         }
    1937          31 :                         last=LOWER_CASE;
    1938          25 :                 } else if (ch >= 'A' && ch <= 'Z') {
    1939           6 :                         if (ch == 'Z') {
    1940           0 :                                 s[pos] = 'A';
    1941           0 :                                 carry=1;
    1942             :                         } else {
    1943           6 :                                 s[pos]++;
    1944           6 :                                 carry=0;
    1945             :                         }
    1946           6 :                         last=UPPER_CASE;
    1947          22 :                 } else if (ch >= '0' && ch <= '9') {
    1948           9 :                         if (ch == '9') {
    1949           2 :                                 s[pos] = '0';
    1950           2 :                                 carry=1;
    1951             :                         } else {
    1952           7 :                                 s[pos]++;
    1953           7 :                                 carry=0;
    1954             :                         }
    1955           9 :                         last = NUMERIC;
    1956             :                 } else {
    1957           4 :                         carry=0;
    1958           4 :                         break;
    1959             :                 }
    1960          46 :                 if (carry == 0) {
    1961          42 :                         break;
    1962             :                 }
    1963           4 :                 pos--;
    1964             :         }
    1965             : 
    1966          46 :         if (carry) {
    1967           0 :                 t = (char *) emalloc(Z_STRLEN_P(str)+1+1);
    1968           0 :                 memcpy(t+1, Z_STRVAL_P(str), Z_STRLEN_P(str));
    1969           0 :                 Z_STRLEN_P(str)++;
    1970           0 :                 t[Z_STRLEN_P(str)] = '\0';
    1971           0 :                 switch (last) {
    1972             :                         case NUMERIC:
    1973           0 :                                 t[0] = '1';
    1974           0 :                                 break;
    1975             :                         case UPPER_CASE:
    1976           0 :                                 t[0] = 'A';
    1977           0 :                                 break;
    1978             :                         case LOWER_CASE:
    1979           0 :                                 t[0] = 'a';
    1980             :                                 break;
    1981             :                 }
    1982           0 :                 str_efree(Z_STRVAL_P(str));
    1983           0 :                 Z_STRVAL_P(str) = t;
    1984             :         }
    1985             : }
    1986             : /* }}} */
    1987             : 
    1988        4898 : ZEND_API int increment_function(zval *op1) /* {{{ */
    1989             : {
    1990        4898 :         switch (Z_TYPE_P(op1)) {
    1991             :                 case IS_LONG:
    1992        3200 :                         if (Z_LVAL_P(op1) == LONG_MAX) {
    1993             :                                 /* switch to double */
    1994           0 :                                 double d = (double)Z_LVAL_P(op1);
    1995           0 :                                 ZVAL_DOUBLE(op1, d+1);
    1996             :                         } else {
    1997        3200 :                         Z_LVAL_P(op1)++;
    1998             :                         }
    1999        3200 :                         break;
    2000             :                 case IS_DOUBLE:
    2001           4 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
    2002           4 :                         break;
    2003             :                 case IS_NULL:
    2004          28 :                         ZVAL_LONG(op1, 1);
    2005          28 :                         break;
    2006             :                 case IS_STRING: {
    2007             :                                 long lval;
    2008             :                                 double dval;
    2009             : 
    2010        1663 :                                 switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2011             :                                         case IS_LONG:
    2012        1611 :                                                 str_efree(Z_STRVAL_P(op1));
    2013        1611 :                                                 if (lval == LONG_MAX) {
    2014             :                                                         /* switch to double */
    2015           0 :                                                         double d = (double)lval;
    2016           0 :                                                         ZVAL_DOUBLE(op1, d+1);
    2017             :                                                 } else {
    2018        1611 :                                                         ZVAL_LONG(op1, lval+1);
    2019             :                                                 }
    2020        1611 :                                                 break;
    2021             :                                         case IS_DOUBLE:
    2022           6 :                                                 str_efree(Z_STRVAL_P(op1));
    2023           6 :                                                 ZVAL_DOUBLE(op1, dval+1);
    2024           6 :                                                 break;
    2025             :                                         default:
    2026             :                                                 /* Perl style string increment */
    2027          46 :                                                 increment_string(op1);
    2028             :                                                 break;
    2029             :                                 }
    2030             :                         }
    2031        1663 :                         break;
    2032             :                 case IS_OBJECT:
    2033           3 :                         if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2034             :                                 zval *op2;
    2035             :                                 int res;
    2036             :                                 TSRMLS_FETCH();
    2037             : 
    2038           2 :                                 MAKE_STD_ZVAL(op2);
    2039           2 :                                 ZVAL_LONG(op2, 1);
    2040           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, op2 TSRMLS_CC);
    2041           2 :                                 zval_ptr_dtor(&op2);
    2042             : 
    2043           2 :                                 return res;
    2044             :                         }
    2045           1 :                         return FAILURE;
    2046             :                 default:
    2047           0 :                         return FAILURE;
    2048             :         }
    2049        4895 :         return SUCCESS;
    2050             : }
    2051             : /* }}} */
    2052             : 
    2053      195713 : ZEND_API int decrement_function(zval *op1) /* {{{ */
    2054             : {
    2055             :         long lval;
    2056             :         double dval;
    2057             : 
    2058      195713 :         switch (Z_TYPE_P(op1)) {
    2059             :                 case IS_LONG:
    2060           2 :                         if (Z_LVAL_P(op1) == LONG_MIN) {
    2061           0 :                                 double d = (double)Z_LVAL_P(op1);
    2062           0 :                                 ZVAL_DOUBLE(op1, d-1);
    2063             :                         } else {
    2064           2 :                         Z_LVAL_P(op1)--;
    2065             :                         }
    2066           2 :                         break;
    2067             :                 case IS_DOUBLE:
    2068      195670 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
    2069      195670 :                         break;
    2070             :                 case IS_STRING:         /* Like perl we only support string increment */
    2071          33 :                         if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
    2072           1 :                                 str_efree(Z_STRVAL_P(op1));
    2073           1 :                                 ZVAL_LONG(op1, -1);
    2074           1 :                                 break;
    2075             :                         }
    2076          32 :                         switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2077             :                                 case IS_LONG:
    2078           8 :                                         str_efree(Z_STRVAL_P(op1));
    2079           8 :                                         if (lval == LONG_MIN) {
    2080           1 :                                                 double d = (double)lval;
    2081           1 :                                                 ZVAL_DOUBLE(op1, d-1);
    2082             :                                         } else {
    2083           7 :                                                 ZVAL_LONG(op1, lval-1);
    2084             :                                         }
    2085           8 :                                         break;
    2086             :                                 case IS_DOUBLE:
    2087           7 :                                         str_efree(Z_STRVAL_P(op1));
    2088           7 :                                         ZVAL_DOUBLE(op1, dval - 1);
    2089             :                                         break;
    2090             :                         }
    2091          32 :                         break;
    2092             :                 case IS_OBJECT:
    2093           3 :                         if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2094             :                                 zval *op2;
    2095             :                                 int res;
    2096             :                                 TSRMLS_FETCH();
    2097             : 
    2098           2 :                                 MAKE_STD_ZVAL(op2);
    2099           2 :                                 ZVAL_LONG(op2, 1);
    2100           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, op2 TSRMLS_CC);
    2101           2 :                                 zval_ptr_dtor(&op2);
    2102             : 
    2103           2 :                                 return res;
    2104             :                         }
    2105           1 :                         return FAILURE;
    2106             :                 default:
    2107           5 :                         return FAILURE;
    2108             :         }
    2109             : 
    2110      195705 :         return SUCCESS;
    2111             : }
    2112             : /* }}} */
    2113             : 
    2114        3478 : ZEND_API int zval_is_true(zval *op) /* {{{ */
    2115             : {
    2116        3478 :         convert_to_boolean(op);
    2117        3478 :         return (Z_LVAL_P(op) ? 1 : 0);
    2118             : }
    2119             : /* }}} */
    2120             : 
    2121             : #ifdef ZEND_USE_TOLOWER_L
    2122             : ZEND_API void zend_update_current_locale(void) /* {{{ */
    2123             : {
    2124             :         current_locale = _get_current_locale();
    2125             : }
    2126             : /* }}} */
    2127             : #endif
    2128             : 
    2129    96421425 : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length) /* {{{ */
    2130             : {
    2131    96421425 :         register unsigned char *str = (unsigned char*)source;
    2132    96421425 :         register unsigned char *result = (unsigned char*)dest;
    2133    96421425 :         register unsigned char *end = str + length;
    2134             : 
    2135  1450865402 :         while (str < end) {
    2136  1258022552 :                 *result++ = zend_tolower_ascii(*str++);
    2137             :         }
    2138    96421425 :         *result = '\0';
    2139             : 
    2140    96421425 :         return dest;
    2141             : }
    2142             : /* }}} */
    2143             : 
    2144    89834856 : ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length) /* {{{ */
    2145             : {
    2146    89834856 :         return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
    2147             : }
    2148             : /* }}} */
    2149             : 
    2150     3379914 : ZEND_API void zend_str_tolower(char *str, unsigned int length) /* {{{ */
    2151             : {
    2152     3379914 :         register unsigned char *p = (unsigned char*)str;
    2153     3379914 :         register unsigned char *end = p + length;
    2154             : 
    2155    55379792 :         while (p < end) {
    2156    48619964 :                 *p = zend_tolower_ascii(*p);
    2157    48619964 :                 p++;
    2158             :         }
    2159     3379914 : }
    2160             : /* }}} */
    2161             : 
    2162     2467799 : ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
    2163             : {
    2164             :         int retval;
    2165             : 
    2166     2467799 :         if (s1 == s2) {
    2167        4038 :                 return 0;
    2168             :         }
    2169     2463761 :         retval = memcmp(s1, s2, MIN(len1, len2));
    2170     2463761 :         if (!retval) {
    2171      328363 :                 return (len1 - len2);
    2172             :         } else {
    2173     2135398 :                 return retval;
    2174             :         }
    2175             : }
    2176             : /* }}} */
    2177             : 
    2178       14577 : ZEND_API int zend_binary_strncmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
    2179             : {
    2180             :         int retval;
    2181             : 
    2182       14577 :         if (s1 == s2) {
    2183          45 :                 return 0;
    2184             :         }
    2185       14532 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    2186       14532 :         if (!retval) {
    2187       14256 :                 return (MIN(length, len1) - MIN(length, len2));
    2188             :         } else {
    2189         276 :                 return retval;
    2190             :         }
    2191             : }
    2192             : /* }}} */
    2193             : 
    2194      365182 : ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
    2195             : {
    2196             :         int len;
    2197             :         int c1, c2;
    2198             : 
    2199      365182 :         if (s1 == s2) {
    2200          52 :                 return 0;
    2201             :         }
    2202             : 
    2203      365130 :         len = MIN(len1, len2);
    2204     1693705 :         while (len--) {
    2205     1328272 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2206     1328272 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2207     1328272 :                 if (c1 != c2) {
    2208      364827 :                         return c1 - c2;
    2209             :                 }
    2210             :         }
    2211             : 
    2212         303 :         return len1 - len2;
    2213             : }
    2214             : /* }}} */
    2215             : 
    2216       21193 : ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
    2217             : {
    2218             :         int len;
    2219             :         int c1, c2;
    2220             : 
    2221       21193 :         if (s1 == s2) {
    2222          68 :                 return 0;
    2223             :         }
    2224       21125 :         len = MIN(length, MIN(len1, len2));
    2225       49207 :         while (len--) {
    2226        7422 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2227        7422 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2228        7422 :                 if (c1 != c2) {
    2229         465 :                         return c1 - c2;
    2230             :                 }
    2231             :         }
    2232             : 
    2233       20660 :         return MIN(length, len1) - MIN(length, len2);
    2234             : }
    2235             : /* }}} */
    2236             : 
    2237         109 : ZEND_API int zend_binary_strcasecmp_l(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
    2238             : {
    2239             :         int len;
    2240             :         int c1, c2;
    2241             : 
    2242         109 :         if (s1 == s2) {
    2243           0 :                 return 0;
    2244             :         }
    2245             : 
    2246         109 :         len = MIN(len1, len2);
    2247         508 :         while (len--) {
    2248         374 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2249         374 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2250         374 :                 if (c1 != c2) {
    2251          84 :                         return c1 - c2;
    2252             :                 }
    2253             :         }
    2254             : 
    2255          25 :         return len1 - len2;
    2256             : }
    2257             : /* }}} */
    2258             : 
    2259           1 : ZEND_API int zend_binary_strncasecmp_l(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
    2260             : {
    2261             :         int len;
    2262             :         int c1, c2;
    2263             : 
    2264           1 :         if (s1 == s2) {
    2265           0 :                 return 0;
    2266             :         }
    2267           1 :         len = MIN(length, MIN(len1, len2));
    2268           4 :         while (len--) {
    2269           2 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2270           2 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2271           2 :                 if (c1 != c2) {
    2272           0 :                         return c1 - c2;
    2273             :                 }
    2274             :         }
    2275             : 
    2276           1 :         return MIN(length, len1) - MIN(length, len2);
    2277             : }
    2278             : /* }}} */
    2279             : 
    2280     2121058 : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2281             : {
    2282     2121058 :         return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2283             : }
    2284             : /* }}} */
    2285             : 
    2286           0 : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2287             : {
    2288           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));
    2289             : }
    2290             : /* }}} */
    2291             : 
    2292         109 : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
    2293             : {
    2294         109 :         return zend_binary_strcasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2295             : }
    2296             : /* }}} */
    2297             : 
    2298           0 : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2299             : {
    2300           0 :         return zend_binary_strncasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
    2301             : }
    2302             : /* }}} */
    2303             : 
    2304     2112800 : ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
    2305             : {
    2306             :         int ret1, ret2;
    2307             :         int oflow1, oflow2;
    2308     2112800 :         long lval1 = 0, lval2 = 0;
    2309     2112800 :         double dval1 = 0.0, dval2 = 0.0;
    2310             : 
    2311     2725489 :         if ((ret1=is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
    2312      307052 :                 (ret2=is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) {
    2313             : #if ULONG_MAX == 0xFFFFFFFF
    2314             :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
    2315             :                         ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
    2316             :                         || (oflow1 == -1 && dval1 < -9007199254740991.))) {
    2317             : #else
    2318      306758 :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
    2319             : #endif
    2320             :                         /* both values are integers overflown to the same side, and the
    2321             :                          * double comparison may have resulted in crucial accuracy lost */
    2322        1114 :                         goto string_cmp;
    2323             :                 }
    2324      405817 :                 if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
    2325      100180 :                         if (ret1!=IS_DOUBLE) {
    2326          27 :                                 if (oflow2) {
    2327             :                                         /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
    2328           3 :                                         ZVAL_LONG(result, -1 * oflow2);
    2329           3 :                                         return;
    2330             :                                 }
    2331          24 :                                 dval1 = (double) lval1;
    2332      100153 :                         } else if (ret2!=IS_DOUBLE) {
    2333          24 :                                 if (oflow1) {
    2334           0 :                                         ZVAL_LONG(result, oflow1);
    2335           0 :                                         return;
    2336             :                                 }
    2337          24 :                                 dval2 = (double) lval2;
    2338      100129 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2339             :                                 /* Both values overflowed and have the same sign,
    2340             :                                  * so a numeric comparison would be inaccurate */
    2341           4 :                                 goto string_cmp;
    2342             :                         }
    2343      100173 :                         Z_DVAL_P(result) = dval1 - dval2;
    2344      100173 :                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    2345             :                 } else { /* they both have to be long's */
    2346      205464 :                         ZVAL_LONG(result, lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0));
    2347             :                 }
    2348             :         } else {
    2349             : string_cmp:
    2350     1807160 :                 Z_LVAL_P(result) = zend_binary_zval_strcmp(s1, s2);
    2351     1807160 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
    2352             :         }
    2353             : }
    2354             : /* }}} */
    2355             : 
    2356        2684 : static int hash_zval_compare_function(const zval **z1, const zval **z2 TSRMLS_DC) /* {{{ */
    2357             : {
    2358             :         zval result;
    2359             : 
    2360        2684 :         if (compare_function(&result, (zval *) *z1, (zval *) *z2 TSRMLS_CC)==FAILURE) {
    2361           0 :                 return 1;
    2362             :         }
    2363        2684 :         return Z_LVAL(result);
    2364             : }
    2365             : /* }}} */
    2366             : 
    2367         307 : ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2368             : {
    2369         307 :         return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    2370             : }
    2371             : /* }}} */
    2372             : 
    2373         796 : ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2374             : {
    2375         796 :         ZVAL_LONG(result, ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC));
    2376         796 : }
    2377             : /* }}} */
    2378             : 
    2379         791 : ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC) /* {{{ */
    2380             : {
    2381         791 :         zend_compare_symbol_tables(result, Z_ARRVAL_P(a1), Z_ARRVAL_P(a2) TSRMLS_CC);
    2382         791 : }
    2383             : /* }}} */
    2384             : 
    2385           1 : ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
    2386             : {
    2387           1 :         Z_TYPE_P(result) = IS_LONG;
    2388             : 
    2389           1 :         if (Z_OBJ_HANDLE_P(o1) == Z_OBJ_HANDLE_P(o2)) {
    2390           1 :                 Z_LVAL_P(result) = 0;
    2391           1 :                 return;
    2392             :         }
    2393             : 
    2394           0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2395           0 :                 Z_LVAL_P(result) = 1;
    2396             :         } else {
    2397           0 :                 Z_LVAL_P(result) = Z_OBJ_HT_P(o1)->compare_objects(o1, o2 TSRMLS_CC);
    2398             :         }
    2399             : }
    2400             : /* }}} */
    2401             : 
    2402        7248 : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
    2403             : {
    2404             :         TSRMLS_FETCH();
    2405             : 
    2406        7248 :         Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
    2407        7248 : }
    2408             : /* }}} */
    2409             : 
    2410             : /*
    2411             :  * Local variables:
    2412             :  * tab-width: 4
    2413             :  * c-basic-offset: 4
    2414             :  * indent-tabs-mode: t
    2415             :  * End:
    2416             :  */

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:49:01 +0000 (28 days ago)

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