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: 1120 1305 85.8 %
Date: 2014-12-13 Functions: 71 79 89.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       62363 : ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
      83             : {
      84             :         int retval;
      85             : 
      86       62363 :         if (!str_len) {
      87       41230 :                 str_len = (int)strlen(str);
      88             :         }
      89       62363 :         retval = ZEND_STRTOL(str, NULL, 0);
      90       62363 :         if (str_len>0) {
      91       41745 :                 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       62363 :         return retval;
     107             : }
     108             : /* }}} */
     109             : 
     110     1339765 : ZEND_API zend_long zend_atol(const char *str, int str_len) /* {{{ */
     111             : {
     112             :         zend_long retval;
     113             : 
     114     1339765 :         if (!str_len) {
     115       20483 :                 str_len = (int)strlen(str);
     116             :         }
     117     1339765 :         retval = ZEND_STRTOL(str, NULL, 0);
     118     1339765 :         if (str_len>0) {
     119     1319282 :                 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       61822 :                                 retval *= 1024;
     127             :                                 /* break intentionally missing */
     128             :                         case 'k':
     129             :                         case 'K':
     130       82445 :                                 retval *= 1024;
     131             :                                 break;
     132             :                 }
     133             :         }
     134     1339765 :         return retval;
     135             : }
     136             : /* }}} */
     137             : 
     138      203348 : ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
     139             : {
     140             : try_again:
     141      203348 :         switch (Z_TYPE_P(op)) {
     142             :                 case IS_REFERENCE:
     143           3 :                         if (Z_REFCOUNT_P(op) == 1) {
     144           0 :                                 ZVAL_UNREF(op);
     145             :                         } else {
     146             :                                 Z_DELREF_P(op);
     147           3 :                                 ZVAL_COPY_VALUE(op, Z_REFVAL_P(op));
     148             :                         }
     149           3 :                         goto try_again;
     150             :                 case IS_STRING:
     151             :                         {
     152             :                                 zend_string *str;
     153             : 
     154      101121 :                                 str = Z_STR_P(op);
     155      101121 :                                 if ((Z_TYPE_INFO_P(op)=is_numeric_string(str->val, str->len, &Z_LVAL_P(op), &Z_DVAL_P(op), 1)) == 0) {
     156          40 :                                         ZVAL_LONG(op, 0);
     157             :                                 }
     158             :                                 zend_string_release(str);
     159      101121 :                                 break;
     160             :                         }
     161             :                 case IS_NULL:
     162             :                 case IS_FALSE:
     163          60 :                         ZVAL_LONG(op, 0);
     164          60 :                         break;
     165             :                 case IS_TRUE:
     166          16 :                         ZVAL_LONG(op, 1);
     167          16 :                         break;
     168             :                 case IS_RESOURCE:
     169             :                         {
     170           5 :                                 zend_long l = Z_RES_HANDLE_P(op);
     171           5 :                                 zval_ptr_dtor(op);
     172           5 :                                 ZVAL_LONG(op, l);
     173             :                         }
     174           5 :                         break;
     175             :                 case IS_OBJECT:
     176           5 :                         convert_to_long_base(op, 10);
     177             :                         break;
     178             :         }
     179      203345 : }
     180             : /* }}} */
     181             : 
     182             : /* {{{ zendi_convert_scalar_to_number */
     183             : #define zendi_convert_scalar_to_number(op, holder, result)                      \
     184             :         if (op==result) {                                                                                               \
     185             :                 if (Z_TYPE_P(op) != IS_LONG) {                                                          \
     186             :                         convert_scalar_to_number(op TSRMLS_CC);                                 \
     187             :                 }                                                                                                                       \
     188             :         } else {                                                                                                                \
     189             :                 switch (Z_TYPE_P(op)) {                                                                         \
     190             :                         case IS_STRING:                                                                                 \
     191             :                                 {                                                                                                       \
     192             :                                         if ((Z_TYPE_INFO(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), 1)) == 0) {        \
     193             :                                                 ZVAL_LONG(&(holder), 0);                                                    \
     194             :                                         }                                                                                                               \
     195             :                                         (op) = &(holder);                                                                           \
     196             :                                         break;                                                                                                  \
     197             :                                 }                                                                                                                       \
     198             :                         case IS_NULL:                                                                                                   \
     199             :                         case IS_FALSE:                                                                                                  \
     200             :                                 ZVAL_LONG(&(holder), 0);                                                                    \
     201             :                                 (op) = &(holder);                                                                                   \
     202             :                                 break;                                                                                                          \
     203             :                         case IS_TRUE:                                                                                                   \
     204             :                                 ZVAL_LONG(&(holder), 1);                                                                    \
     205             :                                 (op) = &(holder);                                                                                   \
     206             :                                 break;                                                                                                          \
     207             :                         case IS_RESOURCE:                                                                                               \
     208             :                                 ZVAL_LONG(&(holder), Z_RES_HANDLE_P(op));                                   \
     209             :                                 (op) = &(holder);                                                                                   \
     210             :                                 break;                                                                                                          \
     211             :                         case IS_OBJECT:                                                                                                 \
     212             :                                 ZVAL_DUP(&(holder), op);                                                                            \
     213             :                                 convert_to_long_base(&(holder), 10);                                                \
     214             :                                 if (Z_TYPE(holder) == IS_LONG) {                                                        \
     215             :                                         (op) = &(holder);                                                                           \
     216             :                                 }                                                                                                                       \
     217             :                                 break;                                                                                                          \
     218             :                 }                                                                                                                                       \
     219             :         }
     220             : 
     221             : /* }}} */
     222             : 
     223             : /* {{{ zendi_convert_to_long */
     224             : #define zendi_convert_to_long(op, holder, result)                                       \
     225             :         if (op == result) {                                                                                             \
     226             :                 convert_to_long(op);                                                                            \
     227             :         } else if (Z_TYPE_P(op) != IS_LONG) {                                                   \
     228             :                 switch (Z_TYPE_P(op)) {                                                                         \
     229             :                         case IS_NULL:                                                                                   \
     230             :                         case IS_FALSE:                                                                                  \
     231             :                                 ZVAL_LONG(&(holder), 0);                                                    \
     232             :                                 break;                                                                                          \
     233             :                         case IS_TRUE:                                                                                   \
     234             :                                 ZVAL_LONG(&(holder), 1);                                                    \
     235             :                                 break;                                                                                          \
     236             :                         case IS_DOUBLE:                                                                                 \
     237             :                                 ZVAL_LONG(&holder, zend_dval_to_lval(Z_DVAL_P(op)));\
     238             :                                 break;                                                                                          \
     239             :                         case IS_STRING:                                                                                 \
     240             :                                 ZVAL_LONG(&holder, ZEND_STRTOL(Z_STRVAL_P(op), NULL, 10));\
     241             :                                 break;                                                                                          \
     242             :                         case IS_ARRAY:                                                                                  \
     243             :                                 ZVAL_LONG(&holder, zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);     \
     244             :                                 break;                                                                                          \
     245             :                         case IS_OBJECT:                                                                                 \
     246             :                                 ZVAL_DUP(&(holder), (op));                                                  \
     247             :                                 convert_to_long_base(&(holder), 10);                                \
     248             :                                 break;                                                                                          \
     249             :                         case IS_RESOURCE:                                                                               \
     250             :                                 ZVAL_LONG(&holder, Z_RES_HANDLE_P(op));                             \
     251             :                                 break;                                                                                          \
     252             :                         default:                                                                                                \
     253             :                                 zend_error(E_WARNING, "Cannot convert to ordinal value");     \
     254             :                                 ZVAL_LONG(&holder, 0);                                                              \
     255             :                                 break;                                                                                          \
     256             :                 }                                                                                                                       \
     257             :                 (op) = &(holder);                                                                                   \
     258             :         }
     259             : 
     260             : /* }}} */
     261             : 
     262             : /* {{{ zendi_convert_to_boolean */
     263             : #define zendi_convert_to_boolean(op, holder, result)                            \
     264             :         if (op==result) {                                                                                               \
     265             :                 convert_to_boolean(op);                                                                         \
     266             :         } else if (Z_TYPE_P(op) != IS_FALSE &&                                                  \
     267             :                    Z_TYPE_P(op) != IS_TRUE) {                                                   \
     268             :                 switch (Z_TYPE_P(op)) {                                                                         \
     269             :                         case IS_NULL:                                                                                   \
     270             :                                 ZVAL_BOOL(&holder, 0);                                                              \
     271             :                                 break;                                                                                          \
     272             :                         case IS_RESOURCE:                                                                               \
     273             :                                 ZVAL_BOOL(&holder, Z_RES_HANDLE_P(op) ? 1 : 0);             \
     274             :                                 break;                                                                                          \
     275             :                         case IS_LONG:                                                                                   \
     276             :                                 ZVAL_BOOL(&holder, Z_LVAL_P(op) ? 1 : 0);                   \
     277             :                                 break;                                                                                          \
     278             :                         case IS_DOUBLE:                                                                                 \
     279             :                                 ZVAL_BOOL(&holder, Z_DVAL_P(op) ? 1 : 0);                   \
     280             :                                 break;                                                                                          \
     281             :                         case IS_STRING:                                                                                 \
     282             :                                 if (Z_STRLEN_P(op) == 0                                                         \
     283             :                                         || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {     \
     284             :                                         ZVAL_BOOL(&holder, 0);                                                      \
     285             :                                 } else {                                                                                        \
     286             :                                         ZVAL_BOOL(&holder, 1);                                                      \
     287             :                                 }                                                                                                       \
     288             :                                 break;                                                                                          \
     289             :                         case IS_ARRAY:                                                                                  \
     290             :                                 ZVAL_BOOL(&holder, zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);     \
     291             :                                 break;                                                                                          \
     292             :                         case IS_OBJECT:                                                                                 \
     293             :                                 ZVAL_DUP(&(holder), (op));                                                  \
     294             :                                 convert_to_boolean(&(holder));                                              \
     295             :                                 break;                                                                                          \
     296             :                         default:                                                                                                \
     297             :                                 ZVAL_BOOL(&holder, 0);                                                              \
     298             :                                 break;                                                                                          \
     299             :                 }                                                                                                                       \
     300             :                 (op) = &(holder);                                                                                   \
     301             :         }
     302             : 
     303             : /* }}} */
     304             : 
     305             : /* {{{ convert_object_to_type */
     306             : #define convert_object_to_type(op, dst, ctype, conv_func)                                                                       \
     307             :         ZVAL_UNDEF(dst);                                                                                                                                                \
     308             :         if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                           \
     309             :                 if (Z_OBJ_HT_P(op)->cast_object(op, dst, ctype TSRMLS_CC) == FAILURE) {                              \
     310             :                         zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
     311             :                                 "Object of class %s could not be converted to %s", Z_OBJCE_P(op)->name->val,\
     312             :                         zend_get_type_by_const(ctype));                                                                                                 \
     313             :                 }                                                                                                                                                                       \
     314             :         } else if (Z_OBJ_HT_P(op)->get) {                                                                                                            \
     315             :                 zval *newop = Z_OBJ_HT_P(op)->get(op, dst TSRMLS_CC);                                                                \
     316             :                 if (Z_TYPE_P(newop) != IS_OBJECT) {                                                                                                     \
     317             :                         /* for safety - avoid loop */                                                                                                   \
     318             :                         ZVAL_COPY_VALUE(dst, newop);                                                                                                    \
     319             :                         conv_func(dst);                                                                                                                                 \
     320             :                 }                                                                                                                                                                       \
     321             :         }
     322             : 
     323             : /* }}} */
     324             : 
     325       72534 : ZEND_API void convert_to_long(zval *op) /* {{{ */
     326             : {
     327       72534 :         if (Z_TYPE_P(op) != IS_LONG) {
     328       51848 :                 convert_to_long_base(op, 10);
     329             :         }
     330       72534 : }
     331             : /* }}} */
     332             : 
     333       55574 : ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
     334             : {
     335             :         zend_long tmp;
     336             : 
     337       55574 :         switch (Z_TYPE_P(op)) {
     338             :                 case IS_NULL:
     339             :                 case IS_FALSE:
     340        5866 :                         ZVAL_LONG(op, 0);
     341        5866 :                         break;
     342             :                 case IS_TRUE:
     343        1568 :                         ZVAL_LONG(op, 1);
     344        1568 :                         break;
     345             :                 case IS_RESOURCE: {
     346          13 :                                 zend_long l = Z_RES_HANDLE_P(op);
     347          13 :                                 zval_ptr_dtor(op);
     348          13 :                                 ZVAL_LONG(op, l);
     349             :                         }
     350             :                         /* break missing intentionally */
     351          13 :                         Z_TYPE_INFO_P(op) = IS_LONG;
     352          13 :                         break;
     353             :                 case IS_LONG:
     354        2843 :                         break;
     355             :                 case IS_DOUBLE:
     356        8122 :                         ZVAL_LONG(op, zend_dval_to_lval(Z_DVAL_P(op)));
     357        4061 :                         break;
     358             :                 case IS_STRING:
     359             :                         {
     360       41133 :                                 zend_string *str = Z_STR_P(op);
     361             : 
     362       41133 :                                 ZVAL_LONG(op, ZEND_STRTOL(str->val, NULL, base));
     363             :                                 zend_string_release(str);
     364             :                         }
     365       41133 :                         break;
     366             :                 case IS_ARRAY:
     367          57 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     368             :                         zval_dtor(op);
     369          57 :                         ZVAL_LONG(op, tmp);
     370          57 :                         break;
     371             :                 case IS_OBJECT:
     372             :                         {
     373             :                                 zval dst;
     374             :                                 TSRMLS_FETCH();
     375             : 
     376          33 :                                 convert_object_to_type(op, &dst, IS_LONG, convert_to_long);
     377             :                                 zval_dtor(op);
     378             : 
     379          33 :                                 if (Z_TYPE(dst) == IS_LONG) {
     380          33 :                                         ZVAL_COPY_VALUE(op, &dst);
     381             :                                 } else {
     382           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name->val);
     383             : 
     384           0 :                                         ZVAL_LONG(op, 1);
     385             :                                 }
     386          33 :                                 return;
     387             :                         }
     388             :                 EMPTY_SWITCH_DEFAULT_CASE()
     389             :         }
     390             : }
     391             : /* }}} */
     392             : 
     393        5421 : ZEND_API void convert_to_double(zval *op) /* {{{ */
     394             : {
     395             :         double tmp;
     396             : 
     397        5421 :         switch (Z_TYPE_P(op)) {
     398             :                 case IS_NULL:
     399             :                 case IS_FALSE:
     400         180 :                         ZVAL_DOUBLE(op, 0.0);
     401         180 :                         break;
     402             :                 case IS_TRUE:
     403          59 :                         ZVAL_DOUBLE(op, 1.0);
     404          59 :                         break;
     405             :                 case IS_RESOURCE: {
     406          15 :                                 double d = (double) Z_RES_HANDLE_P(op);
     407          15 :                                 zval_ptr_dtor(op);
     408          15 :                                 ZVAL_DOUBLE(op, d);
     409             :                         }
     410          15 :                         break;
     411             :                 case IS_LONG:
     412        3977 :                         ZVAL_DOUBLE(op, (double) Z_LVAL_P(op));
     413        3977 :                         break;
     414             :                 case IS_DOUBLE:
     415        1101 :                         break;
     416             :                 case IS_STRING:
     417             :                         {
     418          77 :                                 zend_string *str = Z_STR_P(op);
     419             : 
     420          77 :                                 ZVAL_DOUBLE(op, zend_strtod(str->val, NULL));
     421             :                                 zend_string_release(str);
     422             :                         }
     423          77 :                         break;
     424             :                 case IS_ARRAY:
     425           8 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     426             :                         zval_dtor(op);
     427           8 :                         ZVAL_DOUBLE(op, tmp);
     428           8 :                         break;
     429             :                 case IS_OBJECT:
     430             :                         {
     431             :                                 zval dst;
     432             :                                 TSRMLS_FETCH();
     433             : 
     434           4 :                                 convert_object_to_type(op, &dst, IS_DOUBLE, convert_to_double);
     435             :                                 zval_dtor(op);
     436             : 
     437           4 :                                 if (Z_TYPE(dst) == IS_DOUBLE) {
     438           4 :                                         ZVAL_COPY_VALUE(op, &dst);
     439             :                                 } else {
     440           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name->val);
     441             : 
     442           0 :                                         ZVAL_DOUBLE(op, 1.0);
     443             :                                 }
     444             :                                 break;
     445             :                         }
     446             :                 EMPTY_SWITCH_DEFAULT_CASE()
     447             :         }
     448        5421 : }
     449             : /* }}} */
     450             : 
     451         914 : ZEND_API void convert_to_null(zval *op) /* {{{ */
     452             : {
     453         914 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     454           3 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     455             :                         zval org;
     456             :                         TSRMLS_FETCH();
     457             : 
     458           3 :                         ZVAL_COPY_VALUE(&org, op);
     459           3 :                         if (Z_OBJ_HT_P(op)->cast_object(&org, op, IS_NULL TSRMLS_CC) == SUCCESS) {
     460             :                                 zval_dtor(&org);
     461           0 :                                 return;
     462             :                         }
     463           3 :                         ZVAL_COPY_VALUE(op, &org);
     464             :                 }
     465             :         }
     466             : 
     467             :         zval_dtor(op);
     468         914 :         ZVAL_NULL(op);
     469             : }
     470             : /* }}} */
     471             : 
     472      222648 : ZEND_API void convert_to_boolean(zval *op) /* {{{ */
     473             : {
     474             :         int tmp;
     475             : 
     476      222648 :         switch (Z_TYPE_P(op)) {
     477             :                 case IS_FALSE:
     478             :                 case IS_TRUE:
     479      221359 :                         break;
     480             :                 case IS_NULL:
     481         103 :                         ZVAL_BOOL(op, 0);
     482         103 :                         break;
     483             :                 case IS_RESOURCE: {
     484          35 :                                 zend_long l = (Z_RES_HANDLE_P(op) ? 1 : 0);
     485             : 
     486          35 :                                 zval_ptr_dtor(op);
     487          35 :                                 ZVAL_BOOL(op, l);
     488             :                         }
     489          35 :                         break;
     490             :                 case IS_LONG:
     491         878 :                         ZVAL_BOOL(op, Z_LVAL_P(op) ? 1 : 0);
     492         878 :                         break;
     493             :                 case IS_DOUBLE:
     494         112 :                         ZVAL_BOOL(op, Z_DVAL_P(op) ? 1 : 0);
     495         112 :                         break;
     496             :                 case IS_STRING:
     497             :                         {
     498         135 :                                 zend_string *str = Z_STR_P(op);
     499             : 
     500         276 :                                 if (str->len == 0
     501         226 :                                         || (str->len == 1 && str->val[0] == '0')) {
     502          50 :                                         ZVAL_BOOL(op, 0);
     503             :                                 } else {
     504          85 :                                         ZVAL_BOOL(op, 1);
     505             :                                 }
     506             :                                 zend_string_release(str);
     507             :                         }
     508         135 :                         break;
     509             :                 case IS_ARRAY:
     510          22 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     511             :                         zval_dtor(op);
     512          22 :                         ZVAL_BOOL(op, tmp);
     513          22 :                         break;
     514             :                 case IS_OBJECT:
     515             :                         {
     516             :                                 zval dst;
     517             :                                 TSRMLS_FETCH();
     518             : 
     519           4 :                                 convert_object_to_type(op, &dst, _IS_BOOL, convert_to_boolean);
     520             :                                 zval_dtor(op);
     521             : 
     522          12 :                                 if (Z_TYPE(dst) == IS_FALSE || Z_TYPE(dst) == IS_TRUE) {
     523           4 :                                         ZVAL_COPY_VALUE(op, &dst);
     524             :                                 } else {
     525           0 :                                         ZVAL_BOOL(op, 1);
     526             :                                 }
     527             :                                 break;
     528             :                         }
     529             :                 EMPTY_SWITCH_DEFAULT_CASE()
     530             :         }
     531      222648 : }
     532             : /* }}} */
     533             : 
     534          13 : ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     535             : {
     536          13 :         _convert_to_string(op ZEND_FILE_LINE_CC);
     537          13 : }
     538             : /* }}} */
     539             : 
     540       60534 : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     541             : {
     542       60534 :         switch (Z_TYPE_P(op)) {
     543             :                 case IS_UNDEF:
     544             :                 case IS_NULL:
     545             :                 case IS_FALSE: {
     546             :                         TSRMLS_FETCH();
     547        4143 :                         ZVAL_EMPTY_STRING(op);
     548        4143 :                         break;
     549             :                 }
     550             :                 case IS_TRUE:
     551        1654 :                         ZVAL_NEW_STR(op, zend_string_init("1", 1, 0));
     552         827 :                         break;
     553             :                 case IS_STRING:
     554           0 :                         break;
     555             :                 case IS_RESOURCE: {
     556             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     557          49 :                         int len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, Z_RES_HANDLE_P(op));
     558          98 :                         ZVAL_NEW_STR(op, zend_string_init(buf, len, 0));
     559          49 :                         break;
     560             :                 }
     561             :                 case IS_LONG: {
     562       53319 :                         ZVAL_NEW_STR(op, zend_long_to_str(Z_LVAL_P(op)));
     563       53319 :                         break;
     564             :                 }
     565             :                 case IS_DOUBLE: {
     566             :                         zend_string *str;
     567        1969 :                         double dval = Z_DVAL_P(op);
     568             :                         TSRMLS_FETCH();
     569             : 
     570        1969 :                         str = zend_strpprintf(0, "%.*G", (int) EG(precision), dval);
     571             :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     572        1969 :                         ZVAL_NEW_STR(op, str);
     573        1969 :                         break;
     574             :                 }
     575             :                 case IS_ARRAY:
     576         179 :                         zend_error(E_NOTICE, "Array to string conversion");
     577             :                         zval_dtor(op);
     578         358 :                         ZVAL_NEW_STR(op, zend_string_init("Array", sizeof("Array")-1, 0));
     579         179 :                         break;
     580             :                 case IS_OBJECT: {
     581             :                         zval dst;
     582             :                         TSRMLS_FETCH();
     583             : 
     584          48 :                         convert_object_to_type(op, &dst, IS_STRING, convert_to_string);
     585             : 
     586          40 :                         if (Z_TYPE(dst) == IS_STRING) {
     587             :                                 zval_dtor(op);
     588          33 :                                 ZVAL_COPY_VALUE(op, &dst);
     589             :                         } else {
     590           7 :                                 zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name->val);
     591             :                                 zval_dtor(op);
     592          14 :                                 ZVAL_NEW_STR(op, zend_string_init("Object", sizeof("Object")-1, 0));
     593             :                         }
     594             :                         break;
     595             :                 }
     596             :                 EMPTY_SWITCH_DEFAULT_CASE()
     597             :         }
     598       60526 : }
     599             : /* }}} */
     600             : 
     601         119 : static void convert_scalar_to_array(zval *op TSRMLS_DC) /* {{{ */
     602             : {
     603             :         zval entry;
     604             : 
     605         119 :         ZVAL_COPY_VALUE(&entry, op);
     606             : 
     607         119 :         ZVAL_NEW_ARR(op);
     608         119 :         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     609         119 :         zend_hash_index_add_new(Z_ARRVAL_P(op), 0, &entry);
     610         119 : }
     611             : /* }}} */
     612             : 
     613         195 : ZEND_API void convert_to_array(zval *op) /* {{{ */
     614             : {
     615             :         TSRMLS_FETCH();
     616             : 
     617         195 :         switch (Z_TYPE_P(op)) {
     618             :                 case IS_ARRAY:
     619          42 :                         break;
     620             : /* OBJECTS_OPTIMIZE */
     621             :                 case IS_OBJECT:
     622          19 :                         if (Z_OBJCE_P(op) == zend_ce_closure) {
     623           3 :                                 convert_scalar_to_array(op TSRMLS_CC);
     624             :                         } else {
     625          16 :                                 if (Z_OBJ_HT_P(op)->get_properties) {
     626          16 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op TSRMLS_CC);
     627          16 :                                         if (obj_ht) {
     628             :                                                 zval arr;
     629          16 :                                                 ZVAL_NEW_ARR(&arr);
     630          16 :                                                 zend_array_dup(Z_ARRVAL(arr), obj_ht);
     631             :                                                 zval_dtor(op);
     632          16 :                                                 ZVAL_COPY_VALUE(op, &arr);
     633          16 :                                                 return;
     634             :                                         }
     635             :                                 } else {
     636             :                                         zval dst;
     637           0 :                                         convert_object_to_type(op, &dst, IS_ARRAY, convert_to_array);
     638             : 
     639           0 :                                         if (Z_TYPE(dst) == IS_ARRAY) {
     640             :                                                 zval_dtor(op);
     641           0 :                                                 ZVAL_COPY_VALUE(op, &dst);
     642           0 :                                                 return;
     643             :                                         }
     644             :                                 }
     645             : 
     646             :                                 zval_dtor(op);
     647           0 :                                 array_init(op);
     648             :                         }
     649           3 :                         break;
     650             :                 case IS_NULL:
     651          18 :                         ZVAL_NEW_ARR(op);
     652          18 :                         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     653          18 :                         break;
     654             :                 default:
     655         116 :                         convert_scalar_to_array(op TSRMLS_CC);
     656             :                         break;
     657             :         }
     658             : }
     659             : /* }}} */
     660             : 
     661         121 : ZEND_API void convert_to_object(zval *op) /* {{{ */
     662             : {
     663             :         TSRMLS_FETCH();
     664             : 
     665         121 :         switch (Z_TYPE_P(op)) {
     666             :                 case IS_ARRAY:
     667             :                         {
     668          78 :                                 HashTable *properties = emalloc(sizeof(HashTable));
     669          78 :                                 zend_array *arr = Z_ARR_P(op);
     670             : 
     671          78 :                                 memcpy(properties, Z_ARRVAL_P(op), sizeof(HashTable));
     672          78 :                                 object_and_properties_init(op, zend_standard_class_def, properties);
     673          78 :                                 if (--GC_REFCOUNT(arr) == 0) {
     674          78 :                                         efree_size(arr, sizeof(zend_array));
     675             :                                 }
     676          78 :                                 break;
     677             :                         }
     678             :                 case IS_OBJECT:
     679           3 :                         break;
     680             :                 case IS_NULL:
     681           3 :                         object_init(op);
     682           3 :                         break;
     683             :                 default: {
     684             :                         zval tmp;
     685          37 :                         ZVAL_COPY_VALUE(&tmp, op);
     686          37 :                         object_init(op);
     687          37 :                         zend_hash_str_add_new(Z_OBJPROP_P(op), "scalar", sizeof("scalar")-1, &tmp);
     688             :                         break;
     689             :                 }
     690             :         }
     691         121 : }
     692             : /* }}} */
     693             : 
     694           0 : ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
     695             : {
     696             :         zval *arg;
     697             :         va_list ap;
     698             : 
     699           0 :         va_start(ap, argc);
     700             : 
     701           0 :         while (argc--) {
     702           0 :                 arg = va_arg(ap, zval *);
     703           0 :                 convert_to_long_ex(arg);
     704             :         }
     705             : 
     706           0 :         va_end(ap);
     707           0 : }
     708             : /* }}} */
     709             : 
     710           0 : ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
     711             : {
     712             :         zval *arg;
     713             :         va_list ap;
     714             : 
     715           0 :         va_start(ap, argc);
     716             : 
     717           0 :         while (argc--) {
     718           0 :                 arg = va_arg(ap, zval *);
     719           0 :                 convert_to_double_ex(arg);
     720             :         }
     721             : 
     722           0 :         va_end(ap);
     723           0 : }
     724             : /* }}} */
     725             : 
     726           0 : ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
     727             : {
     728             :         zval *arg;
     729             :         va_list ap;
     730             : 
     731           0 :         va_start(ap, argc);
     732             : 
     733           0 :         while (argc--) {
     734           0 :                 arg = va_arg(ap, zval *);
     735           0 :                 convert_to_string_ex(arg);
     736             :         }
     737             : 
     738           0 :         va_end(ap);
     739           0 : }
     740             : /* }}} */
     741             : 
     742        9722 : ZEND_API zend_long _zval_get_long_func(zval *op TSRMLS_DC) /* {{{ */
     743             : {
     744             : try_again:
     745        9722 :         switch (Z_TYPE_P(op)) {
     746             :                 case IS_NULL:
     747             :                 case IS_FALSE:
     748         238 :                         return 0;
     749             :                 case IS_TRUE:
     750         980 :                         return 1;
     751             :                 case IS_RESOURCE:
     752          87 :                         return Z_RES_HANDLE_P(op);
     753             :                 case IS_LONG:
     754           0 :                         return Z_LVAL_P(op);
     755             :                 case IS_DOUBLE:
     756        2830 :                         return zend_dval_to_lval(Z_DVAL_P(op));
     757             :                 case IS_STRING:
     758        6146 :                         return ZEND_STRTOL(Z_STRVAL_P(op), NULL, 10);
     759             :                 case IS_ARRAY:
     760         828 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1 : 0;
     761             :                 case IS_OBJECT:
     762             :                         {
     763             :                                 zval dst;
     764          24 :                                 convert_object_to_type(op, &dst, IS_LONG, convert_to_long);
     765          24 :                                 if (Z_TYPE(dst) == IS_LONG) {
     766          24 :                                         return Z_LVAL(dst);
     767             :                                 } else {
     768           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name->val);
     769           0 :                                         return 1;
     770             :                                 }
     771             :                         }
     772             :                 case IS_REFERENCE:
     773           4 :                         op = Z_REFVAL_P(op);
     774           4 :                         goto try_again;
     775             :                 EMPTY_SWITCH_DEFAULT_CASE()
     776             :         }
     777           0 :         return 0;
     778             : }
     779             : /* }}} */
     780             : 
     781      204838 : ZEND_API double _zval_get_double_func(zval *op TSRMLS_DC) /* {{{ */
     782             : {
     783             : try_again:
     784      204838 :         switch (Z_TYPE_P(op)) {
     785             :                 case IS_NULL:
     786             :                 case IS_FALSE:
     787         125 :                         return 0.0;
     788             :                 case IS_TRUE:
     789         123 :                         return 1.0;
     790             :                 case IS_RESOURCE:
     791          33 :                         return (double) Z_RES_HANDLE_P(op);
     792             :                 case IS_LONG:
     793      203509 :                         return (double) Z_LVAL_P(op);
     794             :                 case IS_DOUBLE:
     795           0 :                         return Z_DVAL_P(op);
     796             :                 case IS_STRING:
     797         652 :                         return zend_strtod(Z_STRVAL_P(op), NULL);
     798             :                 case IS_ARRAY:
     799         373 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1.0 : 0.0;
     800             :                 case IS_OBJECT:
     801             :                         {
     802             :                                 zval dst;
     803          11 :                                 convert_object_to_type(op, &dst, IS_DOUBLE, convert_to_double);
     804             : 
     805          11 :                                 if (Z_TYPE(dst) == IS_DOUBLE) {
     806          11 :                                         return Z_DVAL(dst);
     807             :                                 } else {
     808           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name->val);
     809             : 
     810           0 :                                         return 1.0;
     811             :                                 }
     812             :                         }
     813             :                 case IS_REFERENCE:
     814          12 :                         op = Z_REFVAL_P(op);
     815          12 :                         goto try_again;
     816             :                 EMPTY_SWITCH_DEFAULT_CASE()
     817             :         }
     818           0 :         return 0.0;
     819             : }
     820             : /* }}} */
     821             : 
     822     1548319 : ZEND_API zend_string *_zval_get_string_func(zval *op TSRMLS_DC) /* {{{ */
     823             : {
     824             : try_again:
     825     1548319 :         switch (Z_TYPE_P(op)) {
     826             :                 case IS_UNDEF:
     827             :                 case IS_NULL:
     828             :                 case IS_FALSE:
     829        4758 :                         return STR_EMPTY_ALLOC();
     830             :                 case IS_TRUE:
     831        1206 :                         return zend_string_init("1", 1, 0);
     832             :                 case IS_RESOURCE: {
     833             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     834             :                         int len;
     835             : 
     836         653 :                         len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, Z_RES_HANDLE_P(op));
     837        1306 :                         return zend_string_init(buf, len, 0);
     838             :                 }
     839             :                 case IS_LONG: {
     840      448340 :                         return zend_long_to_str(Z_LVAL_P(op));
     841             :                 }
     842             :                 case IS_DOUBLE: {
     843        7671 :                         return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
     844             :                 }
     845             :                 case IS_ARRAY:
     846         905 :                         zend_error(E_NOTICE, "Array to string conversion");
     847         905 :                         return zend_string_init("Array", sizeof("Array")-1, 0);
     848             :                 case IS_OBJECT: {
     849             :                         zval tmp;
     850      103565 :                         if (Z_OBJ_HT_P(op)->cast_object) {
     851      103565 :                                 if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_STRING TSRMLS_CC) == SUCCESS) {
     852      103505 :                                         return Z_STR(tmp);
     853             :                                 }
     854           0 :                         } else if (Z_OBJ_HT_P(op)->get) {
     855           0 :                                 zval *z = Z_OBJ_HT_P(op)->get(op, &tmp TSRMLS_CC);
     856           0 :                                 if (Z_TYPE_P(z) != IS_OBJECT) {
     857           0 :                                         zend_string *str = zval_get_string(z);
     858           0 :                                         zval_ptr_dtor(z);
     859           0 :                                         return str;
     860             :                                 }
     861           0 :                                 zval_ptr_dtor(z);
     862             :                         }
     863          56 :                         zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", Z_OBJCE_P(op)->name->val);
     864          46 :                         return STR_EMPTY_ALLOC();
     865             :                 }
     866             :                 case IS_REFERENCE:
     867      497765 :                         op = Z_REFVAL_P(op);
     868      497765 :                         goto try_again;
     869             :                 case IS_STRING:
     870      966912 :                         return zend_string_copy(Z_STR_P(op));
     871             :                 EMPTY_SWITCH_DEFAULT_CASE()
     872             :         }
     873           0 :         return NULL;
     874             : }
     875             : /* }}} */
     876             : 
     877      855861 : ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     878             : {
     879             :         zval op1_copy, op2_copy;
     880      855861 :         int converted = 0;
     881             : 
     882             :         while (1) {
     883     1712724 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     884             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     885      855539 :                                 zend_long lval = Z_LVAL_P(op1) + Z_LVAL_P(op2);
     886             : 
     887             :                                 /* check for overflow by comparing sign bits */
     888     1710984 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     889     1710966 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     890             : 
     891          18 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
     892             :                                 } else {
     893      855521 :                                         ZVAL_LONG(result, lval);
     894             :                                 }
     895      855539 :                                 return SUCCESS;
     896             :                         }
     897             : 
     898             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     899         176 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     900         176 :                                 return SUCCESS;
     901             : 
     902             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     903          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     904          61 :                                 return SUCCESS;
     905             : 
     906             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     907          64 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     908          64 :                                 return SUCCESS;
     909             : 
     910             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
     911          12 :                                 if ((result == op1) && (result == op2)) {
     912             :                                         /* $a += $a */
     913           1 :                                         return SUCCESS;
     914             :                                 }
     915          11 :                                 if (result != op1) {
     916          10 :                                         ZVAL_DUP(result, op1);
     917             :                                 }
     918          11 :                                 zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0);
     919          11 :                                 return SUCCESS;
     920             : 
     921             :                         default:
     922         510 :                                 if (Z_ISREF_P(op1)) {
     923          23 :                                         op1 = Z_REFVAL_P(op1);
     924         487 :                                 } else if (Z_ISREF_P(op2)) {
     925          18 :                                         op2 = Z_REFVAL_P(op2);
     926         469 :                                 } else if (!converted) {
     927        1392 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function);
     928             : 
     929        1248 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     930        1159 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     931         460 :                                         converted = 1;
     932             :                                 } else {
     933           4 :                                         zend_error(E_ERROR, "Unsupported operand types");
     934           0 :                                         return FAILURE; /* unknown datatype */
     935             :                                 }
     936             :                 }
     937         501 :         }
     938             : }
     939             : /* }}} */
     940             : 
     941       63041 : ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     942             : {
     943             :         zval op1_copy, op2_copy;
     944       63041 :         int converted = 0;
     945             : 
     946             :         while (1) {
     947      126570 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     948             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     949       61251 :                                 zend_long lval = Z_LVAL_P(op1) - Z_LVAL_P(op2);
     950             : 
     951             :                                 /* check for overflow by comparing sign bits */
     952       61424 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     953       61422 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     954             : 
     955           2 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
     956             :                                 } else {
     957       61249 :                                         ZVAL_LONG(result, lval);
     958             :                                 }
     959       61251 :                                 return SUCCESS;
     960             : 
     961             :                         }
     962             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     963        1699 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     964        1699 :                                 return SUCCESS;
     965             : 
     966             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     967          45 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     968          45 :                                 return SUCCESS;
     969             : 
     970             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     971          39 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     972          39 :                                 return SUCCESS;
     973             : 
     974             :                         default:
     975         251 :                                 if (Z_ISREF_P(op1)) {
     976           8 :                                         op1 = Z_REFVAL_P(op1);
     977         243 :                                 } else if (Z_ISREF_P(op2)) {
     978           7 :                                         op2 = Z_REFVAL_P(op2);
     979         236 :                                 } else if (!converted) {
     980         702 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function);
     981             : 
     982         671 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     983         672 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     984         229 :                                         converted = 1;
     985             :                                 } else {
     986           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     987           0 :                                         return FAILURE; /* unknown datatype */
     988             :                                 }
     989             :                 }
     990         244 :         }
     991             : }
     992             : /* }}} */
     993             : 
     994         367 : ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
     995             : {
     996             :         zval op1_copy, op2_copy;
     997         367 :         int converted = 0;
     998             : 
     999             :         while (1) {
    1000        1206 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1001             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
    1002             :                                 zend_long overflow;
    1003             : 
    1004         217 :                                 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
    1005         217 :                                 Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
    1006         217 :                                 return SUCCESS;
    1007             : 
    1008             :                         }
    1009             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1010          45 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
    1011          45 :                                 return SUCCESS;
    1012             : 
    1013             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1014          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
    1015          61 :                                 return SUCCESS;
    1016             : 
    1017             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1018          39 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
    1019          39 :                                 return SUCCESS;
    1020             : 
    1021             :                         default:
    1022         241 :                                 if (Z_ISREF_P(op1)) {
    1023           4 :                                         op1 = Z_REFVAL_P(op1);
    1024         237 :                                 } else if (Z_ISREF_P(op2)) {
    1025           4 :                                         op2 = Z_REFVAL_P(op2);
    1026         233 :                                 } else if (!converted) {
    1027         693 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function);
    1028             : 
    1029         681 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1030         654 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1031         228 :                                         converted = 1;
    1032             :                                 } else {
    1033           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1034           0 :                                         return FAILURE; /* unknown datatype */
    1035             :                                 }
    1036             :                 }
    1037         236 :         }
    1038             : }
    1039             : /* }}} */
    1040             : 
    1041        2229 : ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1042             : {
    1043             :         zval op1_copy, op2_copy;
    1044        2229 :         int converted = 0;
    1045             : 
    1046             :         while (1) {
    1047        4598 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1048             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1049        1514 :                                 if (Z_LVAL_P(op2) >= 0) {
    1050         831 :                                         zend_long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
    1051             : 
    1052         831 :                                         if (i == 0) {
    1053          26 :                                                 ZVAL_LONG(result, 1L);
    1054          26 :                                                 return SUCCESS;
    1055         805 :                                         } else if (l2 == 0) {
    1056          14 :                                                 ZVAL_LONG(result, 0);
    1057          14 :                                                 return SUCCESS;
    1058             :                                         }
    1059             : 
    1060        6653 :                                         while (i >= 1) {
    1061             :                                                 zend_long overflow;
    1062        5161 :                                                 double dval = 0.0;
    1063             : 
    1064        5161 :                                                 if (i % 2) {
    1065        2004 :                                                         --i;
    1066        2004 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
    1067        2004 :                                                         if (overflow) {
    1068          17 :                                                                 ZVAL_DOUBLE(result, dval * pow(l2, i));
    1069          17 :                                                                 return SUCCESS;
    1070             :                                                         }
    1071             :                                                 } else {
    1072        3157 :                                                         i /= 2;
    1073        3157 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
    1074        3157 :                                                         if (overflow) {
    1075          73 :                                                                 ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
    1076          73 :                                                                 return SUCCESS;
    1077             :                                                         }
    1078             :                                                 }
    1079             :                                         }
    1080             :                                         /* i == 0 */
    1081         701 :                                         ZVAL_LONG(result, l1);
    1082             :                                 } else {
    1083         683 :                                         ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
    1084             :                                 }
    1085        1384 :                                 return SUCCESS;
    1086             : 
    1087             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1088         501 :                                 ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
    1089         501 :                                 return SUCCESS;
    1090             : 
    1091             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1092         144 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
    1093         144 :                                 return SUCCESS;
    1094             : 
    1095             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1096          65 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
    1097          65 :                                 return SUCCESS;
    1098             : 
    1099             :                         default:
    1100          75 :                                 if (Z_ISREF_P(op1)) {
    1101           0 :                                         op1 = Z_REFVAL_P(op1);
    1102          75 :                                 } else if (Z_ISREF_P(op2)) {
    1103           1 :                                         op2 = Z_REFVAL_P(op2);
    1104          74 :                                 } else if (!converted) {
    1105         220 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW, pow_function);
    1106             : 
    1107          71 :                                         if (Z_TYPE_P(op1) == IS_ARRAY) {
    1108           1 :                                                 ZVAL_LONG(result, 0);
    1109           1 :                                                 return SUCCESS;
    1110             :                                         } else {
    1111         185 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1112             :                                         }
    1113          70 :                                         if (Z_TYPE_P(op2) == IS_ARRAY) {
    1114           1 :                                                 ZVAL_LONG(result, 1L);
    1115           1 :                                                 return SUCCESS;
    1116             :                                         } else {
    1117         144 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1118             :                                         }
    1119          69 :                                         converted = 1;
    1120             :                                 } else {
    1121           0 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1122           0 :                                         return FAILURE;
    1123             :                                 }
    1124             :                 }
    1125          70 :         }
    1126             : }
    1127             : /* }}} */
    1128             : 
    1129      146222 : ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1130             : {
    1131             :         zval op1_copy, op2_copy;
    1132      146222 :         int converted = 0;
    1133             : 
    1134             :         while (1) {
    1135      292862 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1136             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1137      134604 :                                 if (Z_LVAL_P(op2) == 0) {
    1138          43 :                                         zend_error(E_WARNING, "Division by zero");
    1139          43 :                                         ZVAL_BOOL(result, 0);
    1140          43 :                                         return FAILURE;                 /* division by zero */
    1141      134561 :                                 } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN) {
    1142             :                                         /* Prevent overflow error/crash */
    1143           1 :                                         ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
    1144           1 :                                         return SUCCESS;
    1145             :                                 }
    1146      134560 :                                 if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
    1147       83576 :                                         ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
    1148             :                                 } else {
    1149       50984 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
    1150             :                                 }
    1151      134560 :                                 return SUCCESS;
    1152             : 
    1153             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1154       11486 :                                 if (Z_LVAL_P(op2) == 0) {
    1155          17 :                                         zend_error(E_WARNING, "Division by zero");
    1156          17 :                                         ZVAL_BOOL(result, 0);
    1157          17 :                                         return FAILURE;                 /* division by zero */
    1158             :                                 }
    1159       11469 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
    1160       11469 :                                 return SUCCESS;
    1161             : 
    1162             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1163          66 :                                 if (Z_DVAL_P(op2) == 0) {
    1164           0 :                                         zend_error(E_WARNING, "Division by zero");
    1165           0 :                                         ZVAL_BOOL(result, 0);
    1166           0 :                                         return FAILURE;                 /* division by zero */
    1167             :                                 }
    1168          66 :                                 ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
    1169          66 :                                 return SUCCESS;
    1170             : 
    1171             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1172          61 :                                 if (Z_DVAL_P(op2) == 0) {
    1173           0 :                                         zend_error(E_WARNING, "Division by zero");
    1174           0 :                                         ZVAL_BOOL(result, 0);
    1175           0 :                                         return FAILURE;                 /* division by zero */
    1176             :                                 }
    1177          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
    1178          61 :                                 return SUCCESS;
    1179             : 
    1180             :                         default:
    1181         214 :                                 if (Z_ISREF_P(op1)) {
    1182           0 :                                         op1 = Z_REFVAL_P(op1);
    1183         214 :                                 } else if (Z_ISREF_P(op2)) {
    1184           7 :                                         op2 = Z_REFVAL_P(op2);
    1185         207 :                                 } else if (!converted) {
    1186         615 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function);
    1187             : 
    1188         603 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1189         601 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1190         202 :                                         converted = 1;
    1191             :                                 } else {
    1192           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1193           0 :                                         return FAILURE; /* unknown datatype */
    1194             :                                 }
    1195             :                 }
    1196         209 :         }
    1197             : }
    1198             : /* }}} */
    1199             : 
    1200         344 : ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1201             : {
    1202             :         zval op1_copy, op2_copy;
    1203             :         zend_long op1_lval;
    1204             : 
    1205             :         do {
    1206         344 :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1207         321 :                         if (Z_ISREF_P(op1)) {
    1208           0 :                                 op1 = Z_REFVAL_P(op1);
    1209           0 :                                 if (Z_TYPE_P(op1) == IS_LONG) break;
    1210             :                         }
    1211         642 :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_MOD, mod_function);
    1212        1075 :                         zendi_convert_to_long(op1, op1_copy, result);
    1213             :                 }
    1214             :         } while (0);
    1215         341 :         op1_lval = Z_LVAL_P(op1);
    1216             :         do {
    1217         341 :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1218         318 :                         if (Z_ISREF_P(op2)) {
    1219           0 :                                 op2 = Z_REFVAL_P(op2);
    1220           0 :                                 if (Z_TYPE_P(op2) == IS_LONG) break;
    1221             :                         }
    1222         318 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_MOD);
    1223        1071 :                         zendi_convert_to_long(op2, op2_copy, result);
    1224             :                 }
    1225             :         } while (0);
    1226             : 
    1227         340 :         if (Z_LVAL_P(op2) == 0) {
    1228          45 :                 zend_error(E_WARNING, "Division by zero");
    1229          45 :                 ZVAL_BOOL(result, 0);
    1230          45 :                 return FAILURE;                 /* modulus by zero */
    1231             :         }
    1232             : 
    1233         295 :         if (Z_LVAL_P(op2) == -1) {
    1234             :                 /* Prevent overflow error/crash if op1==LONG_MIN */
    1235           5 :                 ZVAL_LONG(result, 0);
    1236           5 :                 return SUCCESS;
    1237             :         }
    1238             : 
    1239         290 :         ZVAL_LONG(result, op1_lval % Z_LVAL_P(op2));
    1240         290 :         return SUCCESS;
    1241             : }
    1242             : /* }}} */
    1243             : 
    1244           2 : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1245             : {
    1246             :         zval op1_copy, op2_copy;
    1247             :         int op1_val, op2_val;
    1248             : 
    1249             :         do {
    1250           2 :                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1251           0 :                         op1_val = 0;
    1252           2 :                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1253           0 :                         op1_val = 1;
    1254             :                 } else {
    1255           2 :                         if (Z_ISREF_P(op1)) {
    1256           0 :                                 op1 = Z_REFVAL_P(op1);
    1257           0 :                                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1258           0 :                                         op1_val = 0;
    1259           0 :                                         break;
    1260           0 :                                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1261           0 :                                         op1_val = 1;
    1262           0 :                                         break;
    1263             :                                 }
    1264             :                         }
    1265           4 :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BOOL_XOR, boolean_xor_function);
    1266           8 :                         zendi_convert_to_boolean(op1, op1_copy, result);
    1267           2 :                         op1_val = (Z_TYPE_P(op1) == IS_TRUE);
    1268             :                 }
    1269             :         } while (0);
    1270             :         do {
    1271           2 :                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1272           0 :                         op2_val = 0;
    1273           2 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1274           0 :                         op2_val = 1;
    1275             :                 } else {
    1276           2 :                         if (Z_ISREF_P(op2)) {
    1277           0 :                                 op2 = Z_REFVAL_P(op2);
    1278           0 :                                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1279           0 :                                         op2_val = 0;
    1280           0 :                                         break;
    1281           0 :                                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1282           0 :                                         op2_val = 1;
    1283           0 :                                         break;
    1284             :                                 }
    1285             :                         }
    1286           2 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BOOL_XOR);
    1287           8 :                         zendi_convert_to_boolean(op2, op2_copy, result);
    1288           2 :                         op2_val = (Z_TYPE_P(op2) == IS_TRUE);
    1289             :                 }
    1290             :         } while (0);
    1291             : 
    1292           2 :         ZVAL_BOOL(result, op1_val ^ op2_val);
    1293           2 :         return SUCCESS;
    1294             : }
    1295             : /* }}} */
    1296             : 
    1297         174 : ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1298             : {
    1299             :         zval op1_copy;
    1300             : 
    1301         174 :         if (Z_TYPE_P(op1) < IS_TRUE) {
    1302           0 :                 ZVAL_TRUE(result);
    1303         174 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1304         173 :                 ZVAL_FALSE(result);
    1305             :         } else {
    1306           1 :                 if (Z_ISREF_P(op1)) {
    1307           0 :                         op1 = Z_REFVAL_P(op1);
    1308           0 :                         if (Z_TYPE_P(op1) < IS_TRUE) {
    1309           0 :                                 ZVAL_TRUE(result);
    1310           0 :                                 return SUCCESS;
    1311           0 :                         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1312           0 :                                 ZVAL_FALSE(result);
    1313           0 :                                 return SUCCESS;
    1314             :                         }
    1315             :                 }
    1316           1 :                 ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
    1317             : 
    1318           4 :                 zendi_convert_to_boolean(op1, op1_copy, result);
    1319             : 
    1320           1 :                 ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_FALSE);
    1321             :         }
    1322         174 :         return SUCCESS;
    1323             : }
    1324             : /* }}} */
    1325             : 
    1326         149 : ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
    1327             : {
    1328             : try_again:
    1329         149 :         switch (Z_TYPE_P(op1)) {
    1330             :                 case IS_LONG:
    1331         129 :                         ZVAL_LONG(result, ~Z_LVAL_P(op1));
    1332         129 :                         return SUCCESS;
    1333             :                 case IS_DOUBLE:
    1334           6 :                         ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
    1335           3 :                         return SUCCESS;
    1336             :                 case IS_STRING: {
    1337             :                         size_t i;
    1338             : 
    1339          30 :                         ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0));
    1340          83 :                         for (i = 0; i < Z_STRLEN_P(op1); i++) {
    1341          68 :                                 Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
    1342             :                         }
    1343          15 :                         Z_STRVAL_P(result)[i] = 0;
    1344          15 :                         return SUCCESS;
    1345             :                 }
    1346             :                 case IS_REFERENCE:
    1347           0 :                         op1 = Z_REFVAL_P(op1);
    1348           0 :                         goto try_again;
    1349             :                 default:
    1350           2 :                         ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
    1351             : 
    1352           1 :                         zend_error(E_ERROR, "Unsupported operand types");
    1353           0 :                         return FAILURE;
    1354             :         }
    1355             : }
    1356             : /* }}} */
    1357             : 
    1358      454345 : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1359             : {
    1360             :         zval op1_copy, op2_copy;
    1361             :         zend_long op1_lval;
    1362             : 
    1363      908470 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1364      454105 :                 ZVAL_LONG(result, Z_LVAL_P(op1) | Z_LVAL_P(op2));
    1365      454105 :                 return SUCCESS;
    1366             :         }
    1367             :         
    1368         240 :         ZVAL_DEREF(op1);
    1369         240 :         ZVAL_DEREF(op2);
    1370             : 
    1371         440 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1372             :                 zval *longer, *shorter;
    1373             :                 zend_string *str;
    1374             :                 size_t i;
    1375             : 
    1376         200 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1377         117 :                         longer = op1;
    1378         117 :                         shorter = op2;
    1379             :                 } else {
    1380          83 :                         longer = op2;
    1381          83 :                         shorter = op1;
    1382             :                 }
    1383             : 
    1384         400 :                 str = zend_string_alloc(Z_STRLEN_P(longer), 0);
    1385         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1386         688 :                         str->val[i] = Z_STRVAL_P(longer)[i] | Z_STRVAL_P(shorter)[i];
    1387             :                 }
    1388         200 :                 memcpy(str->val + i, Z_STRVAL_P(longer) + i, Z_STRLEN_P(longer) - i + 1);
    1389         200 :                 if (result==op1) {
    1390           1 :                         zend_string_release(Z_STR_P(result));
    1391             :                 }
    1392         200 :                 ZVAL_NEW_STR(result, str);
    1393         200 :                 return SUCCESS;
    1394             :         }
    1395             : 
    1396          40 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1397          40 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
    1398          72 :                 zendi_convert_to_long(op1, op1_copy, result);
    1399             :         }
    1400          38 :         op1_lval = Z_LVAL_P(op1);
    1401          38 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1402          20 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
    1403          75 :                 zendi_convert_to_long(op2, op2_copy, result);
    1404             :         }
    1405             : 
    1406          37 :         ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
    1407          37 :         return SUCCESS;
    1408             : }
    1409             : /* }}} */
    1410             : 
    1411      359540 : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1412             : {
    1413             :         zval op1_copy, op2_copy;
    1414             :         zend_long op1_lval;
    1415             : 
    1416      718847 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1417      359228 :                 ZVAL_LONG(result, Z_LVAL_P(op1) & Z_LVAL_P(op2));
    1418      359228 :                 return SUCCESS;
    1419             :         }
    1420             :         
    1421         312 :         ZVAL_DEREF(op1);
    1422         312 :         ZVAL_DEREF(op2);
    1423             : 
    1424         513 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1425             :                 zval *longer, *shorter;
    1426             :                 zend_string *str;
    1427             :                 size_t i;
    1428             : 
    1429         201 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1430         117 :                         longer = op1;
    1431         117 :                         shorter = op2;
    1432             :                 } else {
    1433          84 :                         longer = op2;
    1434          84 :                         shorter = op1;
    1435             :                 }
    1436             : 
    1437         402 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1438         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1439         687 :                         str->val[i] = Z_STRVAL_P(shorter)[i] & Z_STRVAL_P(longer)[i];
    1440             :                 }
    1441         201 :                 str->val[i] = 0;
    1442         201 :                 if (result==op1) {
    1443           1 :                         zend_string_release(Z_STR_P(result));
    1444             :                 }
    1445         201 :                 ZVAL_NEW_STR(result, str);
    1446         201 :                 return SUCCESS;
    1447             :         }
    1448             : 
    1449         111 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1450          64 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
    1451          98 :                 zendi_convert_to_long(op1, op1_copy, result);
    1452             :         }
    1453         109 :         op1_lval = Z_LVAL_P(op1);
    1454         109 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1455          25 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
    1456          90 :                 zendi_convert_to_long(op2, op2_copy, result);
    1457             :         }
    1458             : 
    1459         108 :         ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
    1460         108 :         return SUCCESS;
    1461             : }
    1462             : /* }}} */
    1463             : 
    1464         488 : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1465             : {
    1466             :         zval op1_copy, op2_copy;
    1467             :         zend_long op1_lval;
    1468             : 
    1469         750 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1470         243 :                 ZVAL_LONG(result, Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
    1471         243 :                 return SUCCESS;
    1472             :         }
    1473             :         
    1474         245 :         ZVAL_DEREF(op1);
    1475         245 :         ZVAL_DEREF(op2);
    1476             : 
    1477         447 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1478             :                 zval *longer, *shorter;
    1479             :                 zend_string *str;
    1480             :                 size_t i;
    1481             : 
    1482         202 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1483         118 :                         longer = op1;
    1484         118 :                         shorter = op2;
    1485             :                 } else {
    1486          84 :                         longer = op2;
    1487          84 :                         shorter = op1;
    1488             :                 }
    1489             : 
    1490         404 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1491         892 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1492         690 :                         str->val[i] = Z_STRVAL_P(shorter)[i] ^ Z_STRVAL_P(longer)[i];
    1493             :                 }
    1494         202 :                 str->val[i] = 0;
    1495         202 :                 if (result==op1) {
    1496           1 :                         zend_string_release(Z_STR_P(result));
    1497             :                 }
    1498         202 :                 ZVAL_NEW_STR(result, str);
    1499         202 :                 return SUCCESS;
    1500             :         }
    1501             : 
    1502          43 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1503          48 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
    1504          84 :                 zendi_convert_to_long(op1, op1_copy, result);
    1505             :         }
    1506          41 :         op1_lval = Z_LVAL_P(op1);
    1507          41 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1508          23 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
    1509          84 :                 zendi_convert_to_long(op2, op2_copy, result);
    1510             :         }
    1511             : 
    1512          40 :         ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
    1513          40 :         return SUCCESS;
    1514             : }
    1515             : /* }}} */
    1516             : 
    1517        4434 : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1518             : {
    1519             :         zval op1_copy, op2_copy;
    1520             :         zend_long op1_lval;
    1521             : 
    1522             :         do {
    1523        4434 :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1524        1224 :                         if (Z_ISREF_P(op1)) {
    1525           0 :                                 op1 = Z_REFVAL_P(op1);
    1526           0 :                                 if (Z_TYPE_P(op1) == IS_LONG) break;
    1527             :                         }
    1528        2448 :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SL, shift_left_function);
    1529         672 :                         zendi_convert_to_long(op1, op1_copy, result);
    1530             :                 }
    1531             :         } while (0);
    1532        3430 :         op1_lval = Z_LVAL_P(op1);
    1533             :         do {
    1534        3430 :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1535         218 :                         if (Z_ISREF_P(op2)) {
    1536           0 :                                 op2 = Z_REFVAL_P(op2);
    1537           0 :                                 if (Z_TYPE_P(op2) == IS_LONG) break;
    1538             :                         }
    1539         218 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_SL);
    1540         669 :                         zendi_convert_to_long(op2, op2_copy, result);
    1541             :                 }
    1542             :         } while (0);
    1543             : 
    1544             :         /* prevent wrapping quirkiness on some processors where << 64 + x == << x */
    1545        3429 :         if (Z_LVAL_P(op2) >= SIZEOF_ZEND_LONG * 8) {
    1546         215 :                 ZVAL_LONG(result, 0);
    1547         215 :                 return SUCCESS;
    1548             :         }
    1549             : 
    1550        3214 :         if (Z_LVAL_P(op2) < 0) {
    1551         121 :                 zend_error(E_WARNING, "Bit shift by negative number");
    1552         121 :                 ZVAL_FALSE(result);
    1553         121 :                 return FAILURE;
    1554             :         }
    1555             : 
    1556        3093 :         ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2));
    1557        3093 :         return SUCCESS;
    1558             : }
    1559             : /* }}} */
    1560             : 
    1561      350246 : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1562             : {
    1563             :         zval op1_copy, op2_copy;
    1564             :         zend_long op1_lval;
    1565             : 
    1566             :         do {
    1567      350246 :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1568         223 :                         if (Z_ISREF_P(op1)) {
    1569           0 :                                 op1 = Z_REFVAL_P(op1);
    1570           0 :                                 if (Z_TYPE_P(op1) == IS_LONG) break;
    1571             :                         }
    1572         446 :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SR, shift_right_function);
    1573         672 :                         zendi_convert_to_long(op1, op1_copy, result);
    1574             :                 }
    1575             :         } while (0);
    1576      350243 :         op1_lval = Z_LVAL_P(op1);
    1577             :         do {
    1578      350243 :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1579         217 :                         if (Z_ISREF_P(op2)) {
    1580           0 :                                 op2 = Z_REFVAL_P(op2);
    1581           0 :                                 if (Z_TYPE_P(op2) == IS_LONG) break;
    1582             :                         }
    1583         217 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_SR);
    1584         669 :                         zendi_convert_to_long(op2, op2_copy, result);
    1585             :                 }
    1586             :         } while (0);
    1587             : 
    1588             :         /* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
    1589      350243 :         if (Z_LVAL_P(op2) >= SIZEOF_ZEND_LONG * 8) {
    1590         215 :                 ZVAL_LONG(result, (Z_LVAL_P(op1) < 0) ? -1 : 0);
    1591         215 :                 return SUCCESS;
    1592             :         }
    1593             : 
    1594      350028 :         if (Z_LVAL_P(op2) < 0) {
    1595         121 :                 zend_error(E_WARNING, "Bit shift by negative number");
    1596         121 :                 ZVAL_FALSE(result);
    1597         121 :                 return FAILURE;
    1598             :         }
    1599             : 
    1600      349907 :         ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2));
    1601      349907 :         return SUCCESS;
    1602             : }
    1603             : /* }}} */
    1604             : 
    1605             : /* must support result==op1 */
    1606     1126957 : ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1607             : {
    1608     1126957 :         size_t length = Z_STRLEN_P(op1) + 1;
    1609     2253914 :         zend_string *buf = zend_string_realloc(Z_STR_P(op1), length, 0);
    1610             : 
    1611     1126957 :         buf->val[length - 1] = (char) Z_LVAL_P(op2);
    1612     1126957 :         buf->val[length] = 0;
    1613     1126957 :         ZVAL_NEW_STR(result, buf);
    1614     1126957 :         return SUCCESS;
    1615             : }
    1616             : /* }}} */
    1617             : 
    1618             : /* must support result==op1 */
    1619     3088472 : ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1620             : {
    1621     3088472 :         size_t op1_len = Z_STRLEN_P(op1);
    1622     3088472 :         size_t length = op1_len + Z_STRLEN_P(op2);
    1623     6176944 :         zend_string *buf = zend_string_realloc(Z_STR_P(op1), length, 0);
    1624             : 
    1625     3088472 :         memcpy(buf->val + op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1626     3088472 :         buf->val[length] = 0;
    1627     3088472 :         ZVAL_NEW_STR(result, buf);
    1628     3088472 :         return SUCCESS;
    1629             : }
    1630             : /* }}} */
    1631             : 
    1632     4575301 : ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1633             : {
    1634             :         zval op1_copy, op2_copy;
    1635     4575301 :         int use_copy1 = 0, use_copy2 = 0;
    1636             : 
    1637             :         do {
    1638     4575301 :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) {
    1639       46417 :                         if (Z_ISREF_P(op1)) {
    1640       14968 :                                 op1 = Z_REFVAL_P(op1);
    1641       14968 :                                 if (Z_TYPE_P(op1) == IS_STRING) break;
    1642             :                         }
    1643       94362 :                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
    1644       31455 :                         use_copy1 = zend_make_printable_zval(op1, &op1_copy TSRMLS_CC);
    1645       31455 :                         if (use_copy1) {
    1646             :                                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1647             :                                  * we have to free it.
    1648             :                                  */
    1649       31455 :                                 if (result == op1) {
    1650             :                                         zval_dtor(op1);
    1651           8 :                                         if (UNEXPECTED(op1 == op2)) {
    1652           0 :                                                 op2 = &op1_copy;
    1653             :                                         }
    1654             :                                 }
    1655       31455 :                                 op1 = &op1_copy;
    1656             :                         }
    1657             :                 }
    1658             :         } while (0);
    1659             :         do {
    1660     4575301 :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) {
    1661       24802 :                         if (Z_ISREF_P(op2)) {
    1662          91 :                                 op2 = Z_REFVAL_P(op2);
    1663          91 :                                 if (Z_TYPE_P(op2) == IS_STRING) break;
    1664             :                         }
    1665       24727 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT);
    1666       24727 :                         use_copy2 = zend_make_printable_zval(op2, &op2_copy TSRMLS_CC);
    1667       24727 :                         if (use_copy2) {
    1668       24727 :                                 op2 = &op2_copy;
    1669             :                         }
    1670             :                 }
    1671             :         } while (0);
    1672             : 
    1673             :         {
    1674     4575301 :                 size_t op1_len = Z_STRLEN_P(op1);
    1675     4575301 :                 size_t op2_len = Z_STRLEN_P(op2);
    1676     4575301 :                 size_t result_len = op1_len + op2_len;
    1677             :                 zend_string *result_str;
    1678             : 
    1679     4575301 :                 if (op1_len > SIZE_MAX - op2_len) {
    1680           0 :                         zend_error_noreturn(E_ERROR, "String size overflow");
    1681             :                 }
    1682             : 
    1683     7668130 :                 if (result == op1 && Z_REFCOUNTED_P(result)) {
    1684             :                         /* special case, perform operations on result */
    1685     6185658 :                         result_str = zend_string_realloc(Z_STR_P(result), result_len, 0);
    1686             :                 } else {
    1687     1482472 :                         result_str = zend_string_alloc(result_len, 0);
    1688     1482472 :                         memcpy(result_str->val, Z_STRVAL_P(op1), op1_len);
    1689             :                 }
    1690             : 
    1691             :                 /* This has to happen first to account for the cases where result == op1 == op2 and
    1692             :                  * the realloc is done. In this case this line will also update Z_STRVAL_P(op2) to
    1693             :                  * point to the new string. The first op2_len bytes of result will still be the same. */
    1694     4575301 :                 ZVAL_NEW_STR(result, result_str);
    1695             : 
    1696     4575301 :                 memcpy(result_str->val + op1_len, Z_STRVAL_P(op2), op2_len);
    1697     4575301 :                 result_str->val[result_len] = '\0';
    1698             :         }
    1699             : 
    1700     4575301 :         if (UNEXPECTED(use_copy1)) {
    1701             :                 zval_dtor(op1);
    1702             :         }
    1703     4575301 :         if (UNEXPECTED(use_copy2)) {
    1704             :                 zval_dtor(op2);
    1705             :         }
    1706     4575301 :         return SUCCESS;
    1707             : }
    1708             : /* }}} */
    1709             : 
    1710           0 : ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */
    1711             : {
    1712           0 :         zend_string *str1 = zval_get_string(op1);
    1713           0 :         zend_string *str2 = zval_get_string(op2);
    1714             : 
    1715           0 :         if (case_insensitive) {
    1716           0 :                 ZVAL_LONG(result, zend_binary_strcasecmp_l(str1->val, str1->len, str2->val, str1->len));
    1717             :         } else {
    1718           0 :                 ZVAL_LONG(result, zend_binary_strcmp(str1->val, str1->len, str2->val, str2->len));
    1719             :         }
    1720             : 
    1721             :         zend_string_release(str1);
    1722             :         zend_string_release(str2);
    1723           0 :         return SUCCESS;
    1724             : }
    1725             : /* }}} */
    1726             : 
    1727      296297 : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1728             : {
    1729      749806 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1730      229270 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1731      224239 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1732         254 :                         ZVAL_LONG(result, 0);
    1733             :                 } else {
    1734      223985 :                         ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1735             :                 }
    1736             :         } else {
    1737       72058 :                 zend_string *str1 = zval_get_string(op1);
    1738       72058 :                 zend_string *str2 = zval_get_string(op2);
    1739             : 
    1740       72058 :                 ZVAL_LONG(result, zend_binary_strcmp(str1->val, str1->len, str2->val, str2->len));
    1741             : 
    1742             :                 zend_string_release(str1);
    1743             :                 zend_string_release(str2);
    1744             :         }
    1745      296297 :         return SUCCESS;
    1746             : }
    1747             : /* }}} */
    1748             : 
    1749         109 : ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1750             : {
    1751         295 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1752          93 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1753          93 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1754           0 :                         ZVAL_LONG(result, 0);
    1755             :                 } else {
    1756          93 :                         ZVAL_LONG(result, zend_binary_strcasecmp_l(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1757             :                 }
    1758             :         } else {
    1759          16 :                 zend_string *str1 = zval_get_string(op1);
    1760          16 :                 zend_string *str2 = zval_get_string(op2);
    1761             : 
    1762          16 :                 ZVAL_LONG(result, zend_binary_strcasecmp_l(str1->val, str1->len, str2->val, str1->len));
    1763             : 
    1764             :                 zend_string_release(str1);
    1765             :                 zend_string_release(str2);
    1766             :         }
    1767         109 :         return SUCCESS;
    1768             : }
    1769             : /* }}} */
    1770             : 
    1771             : #if HAVE_STRCOLL
    1772          33 : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1773             : {
    1774          33 :         zend_string *str1 = zval_get_string(op1);
    1775          33 :         zend_string *str2 = zval_get_string(op2);
    1776             : 
    1777          33 :         ZVAL_LONG(result, strcoll(str1->val, str2->val));
    1778             : 
    1779             :         zend_string_release(str1);
    1780             :         zend_string_release(str2);
    1781          33 :         return SUCCESS;
    1782             : }
    1783             : /* }}} */
    1784             : #endif
    1785             : 
    1786         843 : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1787             : {
    1788             :         double d1, d2;
    1789             : 
    1790         843 :         d1 = zval_get_double(op1);
    1791         843 :         d2 = zval_get_double(op2);
    1792             : 
    1793         843 :         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(d1 - d2));
    1794             : 
    1795         843 :         return SUCCESS;
    1796             : }
    1797             : /* }}} */
    1798             : 
    1799         413 : static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
    1800             : {
    1801         413 :         if (Z_REFCOUNTED_P(op)) {
    1802           1 :                 if (Z_REFCOUNT_P(op) == 0) {
    1803             :                         zval_dtor(op);
    1804             :                 } else {
    1805           1 :                         zval_ptr_dtor(op);
    1806             :                 }
    1807             :         }
    1808         413 : }
    1809             : /* }}} */
    1810             : 
    1811      891404 : ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    1812             : {
    1813             :         int ret;
    1814      891404 :         int converted = 0;
    1815             :         zval op1_copy, op2_copy;
    1816             :         zval *op_free, tmp_free;
    1817             : 
    1818             :         while (1) {
    1819     2110628 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1820             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1821       63067 :                                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1822       63067 :                                 return SUCCESS;
    1823             : 
    1824             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1825         500 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
    1826         500 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1827         500 :                                 return SUCCESS;
    1828             : 
    1829             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1830         287 :                                 Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
    1831         287 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1832         287 :                                 return SUCCESS;
    1833             : 
    1834             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1835         346 :                                 if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
    1836          72 :                                         ZVAL_LONG(result, 0);
    1837             :                                 } else {
    1838         274 :                                         Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    1839         274 :                                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1840             :                                 }
    1841         346 :                                 return SUCCESS;
    1842             : 
    1843             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
    1844         753 :                                 zend_compare_arrays(result, op1, op2 TSRMLS_CC);
    1845         753 :                                 return SUCCESS;
    1846             : 
    1847             :                         case TYPE_PAIR(IS_NULL, IS_NULL):
    1848             :                         case TYPE_PAIR(IS_NULL, IS_FALSE):
    1849             :                         case TYPE_PAIR(IS_FALSE, IS_NULL):
    1850             :                         case TYPE_PAIR(IS_FALSE, IS_FALSE):
    1851             :                         case TYPE_PAIR(IS_TRUE, IS_TRUE):
    1852        4554 :                                 ZVAL_LONG(result, 0);
    1853        4554 :                                 return SUCCESS;
    1854             : 
    1855             :                         case TYPE_PAIR(IS_NULL, IS_TRUE):
    1856          12 :                                 ZVAL_LONG(result, -1);
    1857          12 :                                 return SUCCESS;
    1858             : 
    1859             :                         case TYPE_PAIR(IS_TRUE, IS_NULL):
    1860          13 :                                 ZVAL_LONG(result, 1);
    1861          13 :                                 return SUCCESS;
    1862             : 
    1863             :                         case TYPE_PAIR(IS_STRING, IS_STRING):
    1864      344295 :                                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1865         196 :                                         ZVAL_LONG(result, 0);
    1866         196 :                                         return SUCCESS;
    1867             :                                 }
    1868      344099 :                                 zendi_smart_strcmp(result, op1, op2);
    1869      344099 :                                 return SUCCESS;
    1870             : 
    1871             :                         case TYPE_PAIR(IS_NULL, IS_STRING):
    1872       12504 :                                 ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
    1873       12504 :                                 return SUCCESS;
    1874             : 
    1875             :                         case TYPE_PAIR(IS_STRING, IS_NULL):
    1876         139 :                                 ZVAL_LONG(result, Z_STRLEN_P(op1) == 0 ? 0 : 1);
    1877         139 :                                 return SUCCESS;
    1878             : 
    1879             :                         case TYPE_PAIR(IS_OBJECT, IS_NULL):
    1880          49 :                                 ZVAL_LONG(result, 1);
    1881          49 :                                 return SUCCESS;
    1882             : 
    1883             :                         case TYPE_PAIR(IS_NULL, IS_OBJECT):
    1884          15 :                                 ZVAL_LONG(result, -1);
    1885          15 :                                 return SUCCESS;
    1886             : 
    1887             :                         default:
    1888      628780 :                                 if (Z_ISREF_P(op1)) {
    1889      108594 :                                         op1 = Z_REFVAL_P(op1);
    1890      108594 :                                         continue;
    1891      520186 :                                 } else if (Z_ISREF_P(op2)) {
    1892       24457 :                                         op2 = Z_REFVAL_P(op2);
    1893       24457 :                                         continue;
    1894             :                                 }
    1895             : 
    1896      495729 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
    1897       55017 :                                         return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2 TSRMLS_CC);
    1898      440712 :                                 } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
    1899       55006 :                                         return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2 TSRMLS_CC);
    1900             :                                 }
    1901             : 
    1902      732815 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
    1903      346893 :                                         if (Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
    1904             :                                                 /* object handles are identical, apparently this is the same object */
    1905          24 :                                                 ZVAL_LONG(result, 0);
    1906          24 :                                                 return SUCCESS;
    1907             :                                         }
    1908      346869 :                                         if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
    1909      346868 :                                                 ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2 TSRMLS_CC));
    1910      346864 :                                                 return SUCCESS;
    1911             :                                         }
    1912             :                                 }
    1913       38814 :                                 if (Z_TYPE_P(op1) == IS_OBJECT) {
    1914         217 :                                         if (Z_OBJ_HT_P(op1)->get) {
    1915             :                                                 zval rv;
    1916           1 :                                                 op_free = Z_OBJ_HT_P(op1)->get(op1, &rv TSRMLS_CC);
    1917           1 :                                                 ret = compare_function(result, op_free, op2 TSRMLS_CC);
    1918           1 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1919           1 :                                                 return ret;
    1920         216 :                                         } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
    1921         215 :                                                 ZVAL_UNDEF(&tmp_free);
    1922         807 :                                                 if (Z_OBJ_HT_P(op1)->cast_object(op1, &tmp_free, ((Z_TYPE_P(op2) == IS_FALSE || Z_TYPE_P(op2) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op2)) TSRMLS_CC) == FAILURE) {
    1923         112 :                                                         ZVAL_LONG(result, 1);
    1924         112 :                                                         zend_free_obj_get_result(&tmp_free TSRMLS_CC);
    1925         112 :                                                         return SUCCESS;
    1926             :                                                 }
    1927         103 :                                                 ret = compare_function(result, &tmp_free, op2 TSRMLS_CC);
    1928         103 :                                                 zend_free_obj_get_result(&tmp_free TSRMLS_CC);
    1929         103 :                                                 return ret;
    1930             :                                         }
    1931             :                                 }
    1932       38598 :                                 if (Z_TYPE_P(op2) == IS_OBJECT) {
    1933         198 :                                         if (Z_OBJ_HT_P(op2)->get) {
    1934             :                                                 zval rv;
    1935           0 :                                                 op_free = Z_OBJ_HT_P(op2)->get(op2, &rv TSRMLS_CC);
    1936           0 :                                                 ret = compare_function(result, op1, op_free TSRMLS_CC);
    1937           0 :                                                 zend_free_obj_get_result(op_free TSRMLS_CC);
    1938           0 :                                                 return ret;
    1939         198 :                                         } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
    1940         197 :                                                 ZVAL_UNDEF(&tmp_free);
    1941         743 :                                                 if (Z_OBJ_HT_P(op2)->cast_object(op2, &tmp_free, ((Z_TYPE_P(op1) == IS_FALSE || Z_TYPE_P(op1) == IS_TRUE) ? _IS_BOOL : Z_TYPE_P(op1)) TSRMLS_CC) == FAILURE) {
    1942         107 :                                                         ZVAL_LONG(result, -1);
    1943         107 :                                                         zend_free_obj_get_result(&tmp_free TSRMLS_CC);
    1944         107 :                                                         return SUCCESS;
    1945             :                                                 }
    1946          90 :                                                 ret = compare_function(result, op1, &tmp_free TSRMLS_CC);
    1947          90 :                                                 zend_free_obj_get_result(&tmp_free TSRMLS_CC);
    1948          90 :                                                 return ret;
    1949           1 :                                         } else if (Z_TYPE_P(op1) == IS_OBJECT) {
    1950           1 :                                                 ZVAL_LONG(result, 1);
    1951           1 :                                                 return SUCCESS;
    1952             :                                         }
    1953             :                                 }
    1954       38400 :                                 if (!converted) {
    1955       75479 :                                         if (Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op1) == IS_FALSE) {
    1956       11081 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1957        5652 :                                                 ZVAL_LONG(result, (Z_TYPE_P(op2) == IS_TRUE) ? -1 : 0);
    1958        2826 :                                                 return SUCCESS;
    1959       69938 :                                         } else if (Z_TYPE_P(op2) == IS_NULL || Z_TYPE_P(op2) == IS_FALSE) {
    1960       14750 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1961        7576 :                                                 ZVAL_LONG(result, (Z_TYPE_P(op1) == IS_TRUE) ? 1 : 0);
    1962        3788 :                                                 return SUCCESS;
    1963       31226 :                                         } else if (Z_TYPE_P(op1) == IS_TRUE) {
    1964         776 :                                                 zendi_convert_to_boolean(op2, op2_copy, result);
    1965         388 :                                                 ZVAL_LONG(result, (Z_TYPE_P(op2) == IS_TRUE) ? 0 : 1);
    1966         194 :                                                 return SUCCESS;
    1967       31032 :                                         } else if (Z_TYPE_P(op2) == IS_TRUE) {
    1968         692 :                                                 zendi_convert_to_boolean(op1, op1_copy, result);
    1969         346 :                                                 ZVAL_LONG(result, (Z_TYPE_P(op1) == IS_TRUE) ? 0 : -1);
    1970         173 :                                                 return SUCCESS;
    1971             :                                         } else {
    1972       77625 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1973       76392 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1974       30859 :                                                 converted = 1;
    1975             :                                         }
    1976         560 :                                 } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    1977         276 :                                         ZVAL_LONG(result, 1);
    1978         276 :                                         return SUCCESS;
    1979         284 :                                 } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    1980         284 :                                         ZVAL_LONG(result, -1);
    1981         284 :                                         return SUCCESS;
    1982           0 :                                 } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    1983           0 :                                         ZVAL_LONG(result, 1);
    1984           0 :                                         return SUCCESS;
    1985           0 :                                 } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    1986           0 :                                         ZVAL_LONG(result, -1);
    1987           0 :                                         return SUCCESS;
    1988             :                                 } else {
    1989           0 :                                         ZVAL_LONG(result, 0);
    1990           0 :                                         return FAILURE;
    1991             :                                 }
    1992             :                 }
    1993      163910 :         }
    1994             : }
    1995             : /* }}} */
    1996             : 
    1997        1138 : static int hash_zval_identical_function(zval *z1, zval *z2 TSRMLS_DC) /* {{{ */
    1998             : {
    1999             :         zval result;
    2000             : 
    2001             :         /* is_identical_function() returns 1 in case of identity and 0 in case
    2002             :          * of a difference;
    2003             :          * whereas this comparison function is expected to return 0 on identity,
    2004             :          * and non zero otherwise.
    2005             :          */
    2006        1138 :         ZVAL_DEREF(z1);
    2007        1138 :         ZVAL_DEREF(z2);
    2008        1138 :         if (is_identical_function(&result, z1, z2 TSRMLS_CC)==FAILURE) {
    2009           0 :                 return 1;
    2010             :         }
    2011        1138 :         return Z_TYPE(result) != IS_TRUE;
    2012             : }
    2013             : /* }}} */
    2014             : 
    2015     1081635 : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2016             : {
    2017     1081635 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    2018         969 :                 ZVAL_BOOL(result, 0);
    2019         969 :                 return SUCCESS;
    2020             :         }
    2021     1080666 :         switch (Z_TYPE_P(op1)) {
    2022             :                 case IS_NULL:
    2023             :                 case IS_FALSE:
    2024             :                 case IS_TRUE:
    2025       53124 :                         ZVAL_BOOL(result, 1);
    2026       53124 :                         break;
    2027             :                 case IS_LONG:
    2028      920243 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) == Z_LVAL_P(op2));
    2029      920243 :                         break;
    2030             :                 case IS_RESOURCE:
    2031          10 :                         ZVAL_BOOL(result, Z_RES_P(op1) == Z_RES_P(op2));
    2032          10 :                         break;
    2033             :                 case IS_DOUBLE:
    2034         179 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) == Z_DVAL_P(op2));
    2035         179 :                         break;
    2036             :                 case IS_STRING:
    2037       40951 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
    2038       24827 :                                 ZVAL_BOOL(result, 1);
    2039             :                         } else {
    2040       16124 :                                 ZVAL_BOOL(result, (Z_STRLEN_P(op1) == Z_STRLEN_P(op2))
    2041             :                                         && (!memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1))));
    2042             :                         }
    2043       40951 :                         break;
    2044             :                 case IS_ARRAY:
    2045          72 :                         ZVAL_BOOL(result, Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
    2046             :                                 zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1 TSRMLS_CC)==0);
    2047          72 :                         break;
    2048             :                 case IS_OBJECT:
    2049       66087 :                         if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
    2050       66087 :                                 ZVAL_BOOL(result, Z_OBJ_P(op1) == Z_OBJ_P(op2));
    2051             :                         } else {
    2052           0 :                                 ZVAL_BOOL(result, 0);
    2053             :                         }
    2054       66087 :                         break;
    2055             :                 default:
    2056           0 :                         ZVAL_BOOL(result, 0);
    2057           0 :                         return FAILURE;
    2058             :         }
    2059     1080666 :         return SUCCESS;
    2060             : }
    2061             : /* }}} */
    2062             : 
    2063           8 : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2064             : {
    2065           8 :         if (is_identical_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2066           0 :                 return FAILURE;
    2067             :         }
    2068           8 :         ZVAL_BOOL(result, Z_TYPE_P(result) != IS_TRUE);
    2069           8 :         return SUCCESS;
    2070             : }
    2071             : /* }}} */
    2072             : 
    2073         144 : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2074             : {
    2075         144 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2076           0 :                 return FAILURE;
    2077             :         }
    2078         144 :         ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
    2079         144 :         return SUCCESS;
    2080             : }
    2081             : /* }}} */
    2082             : 
    2083         322 : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2084             : {
    2085         322 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2086           0 :                 return FAILURE;
    2087             :         }
    2088         322 :         ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
    2089         322 :         return SUCCESS;
    2090             : }
    2091             : /* }}} */
    2092             : 
    2093        1948 : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2094             : {
    2095        1948 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2096           0 :                 return FAILURE;
    2097             :         }
    2098        1948 :         ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
    2099        1948 :         return SUCCESS;
    2100             : }
    2101             : /* }}} */
    2102             : 
    2103        1286 : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
    2104             : {
    2105        1286 :         if (compare_function(result, op1, op2 TSRMLS_CC) == FAILURE) {
    2106           0 :                 return FAILURE;
    2107             :         }
    2108        1286 :         ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
    2109        1286 :         return SUCCESS;
    2110             : }
    2111             : /* }}} */
    2112             : 
    2113     2435234 : ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC) /* {{{ */
    2114             : {
    2115             :         uint32_t i;
    2116             : 
    2117     3116359 :         for (i=0; i<instance_ce->num_interfaces; i++) {
    2118     1100456 :                 if (instanceof_function(instance_ce->interfaces[i], ce TSRMLS_CC)) {
    2119      419331 :                         return 1;
    2120             :                 }
    2121             :         }
    2122     2015903 :         if (!interfaces_only) {
    2123     4734778 :                 while (instance_ce) {
    2124     2025636 :                         if (instance_ce == ce) {
    2125     1322652 :                                 return 1;
    2126             :                         }
    2127      702984 :                         instance_ce = instance_ce->parent;
    2128             :                 }
    2129             :         }
    2130             : 
    2131      693251 :         return 0;
    2132             : }
    2133             : /* }}} */
    2134             : 
    2135     2370356 : ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC) /* {{{ */
    2136             : {
    2137     2370356 :         return instanceof_function_ex(instance_ce, ce, 0 TSRMLS_CC);
    2138             : }
    2139             : /* }}} */
    2140             : 
    2141             : #define LOWER_CASE 1
    2142             : #define UPPER_CASE 2
    2143             : #define NUMERIC 3
    2144             : 
    2145          55 : static void increment_string(zval *str) /* {{{ */
    2146             : {
    2147          55 :         int carry=0;
    2148          55 :         size_t pos=Z_STRLEN_P(str)-1;
    2149             :         char *s;
    2150             :         zend_string *t;
    2151          55 :         int last=0; /* Shut up the compiler warning */
    2152             :         int ch;
    2153             : 
    2154          55 :         if (Z_STRLEN_P(str) == 0) {
    2155           0 :                 zend_string_release(Z_STR_P(str));
    2156           0 :                 Z_STR_P(str) = zend_string_init("1", sizeof("1")-1, 0);
    2157           0 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2158           0 :                 return;
    2159             :         }
    2160             : 
    2161          55 :         if (!Z_REFCOUNTED_P(str)) {
    2162          10 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2163           5 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2164          50 :         } else if (Z_REFCOUNT_P(str) > 1) {
    2165             :                 Z_DELREF_P(str);
    2166           0 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2167             :         } else {
    2168          50 :                 zend_string_forget_hash_val(Z_STR_P(str));
    2169             :         }
    2170          55 :         s = Z_STRVAL_P(str);
    2171             : 
    2172             :         do {
    2173          68 :                 ch = s[pos];
    2174         107 :                 if (ch >= 'a' && ch <= 'z') {
    2175          39 :                         if (ch == 'z') {
    2176           9 :                                 s[pos] = 'a';
    2177           9 :                                 carry=1;
    2178             :                         } else {
    2179          30 :                                 s[pos]++;
    2180          30 :                                 carry=0;
    2181             :                         }
    2182          39 :                         last=LOWER_CASE;
    2183          40 :                 } else if (ch >= 'A' && ch <= 'Z') {
    2184          11 :                         if (ch == 'Z') {
    2185           4 :                                 s[pos] = 'A';
    2186           4 :                                 carry=1;
    2187             :                         } else {
    2188           7 :                                 s[pos]++;
    2189           7 :                                 carry=0;
    2190             :                         }
    2191          11 :                         last=UPPER_CASE;
    2192          32 :                 } else if (ch >= '0' && ch <= '9') {
    2193          14 :                         if (ch == '9') {
    2194           6 :                                 s[pos] = '0';
    2195           6 :                                 carry=1;
    2196             :                         } else {
    2197           8 :                                 s[pos]++;
    2198           8 :                                 carry=0;
    2199             :                         }
    2200          14 :                         last = NUMERIC;
    2201             :                 } else {
    2202           4 :                         carry=0;
    2203           4 :                         break;
    2204             :                 }
    2205          64 :                 if (carry == 0) {
    2206          45 :                         break;
    2207             :                 }
    2208          19 :         } while (pos-- > 0);
    2209             : 
    2210          55 :         if (carry) {
    2211          12 :                 t = zend_string_alloc(Z_STRLEN_P(str)+1, 0);
    2212           6 :                 memcpy(t->val + 1, Z_STRVAL_P(str), Z_STRLEN_P(str));
    2213           6 :                 t->val[Z_STRLEN_P(str) + 1] = '\0';
    2214           6 :                 switch (last) {
    2215             :                         case NUMERIC:
    2216           2 :                                 t->val[0] = '1';
    2217           2 :                                 break;
    2218             :                         case UPPER_CASE:
    2219           2 :                                 t->val[0] = 'A';
    2220           2 :                                 break;
    2221             :                         case LOWER_CASE:
    2222           2 :                                 t->val[0] = 'a';
    2223             :                                 break;
    2224             :                 }
    2225           6 :                 zend_string_free(Z_STR_P(str));
    2226           6 :                 ZVAL_NEW_STR(str, t);
    2227             :         }
    2228             : }
    2229             : /* }}} */
    2230             : 
    2231       18359 : ZEND_API int increment_function(zval *op1) /* {{{ */
    2232             : {
    2233             : try_again:
    2234       18359 :         switch (Z_TYPE_P(op1)) {
    2235             :                 case IS_LONG:
    2236       18256 :                         if (Z_LVAL_P(op1) == ZEND_LONG_MAX) {
    2237             :                                 /* switch to double */
    2238           0 :                                 double d = (double)Z_LVAL_P(op1);
    2239           0 :                                 ZVAL_DOUBLE(op1, d+1);
    2240             :                         } else {
    2241       18256 :                         Z_LVAL_P(op1)++;
    2242             :                         }
    2243       18256 :                         break;
    2244             :                 case IS_DOUBLE:
    2245           4 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
    2246           4 :                         break;
    2247             :                 case IS_NULL:
    2248          27 :                         ZVAL_LONG(op1, 1);
    2249          27 :                         break;
    2250             :                 case IS_STRING: {
    2251             :                                 zend_long lval;
    2252             :                                 double dval;
    2253             : 
    2254         138 :                                 switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2255             :                                         case IS_LONG:
    2256           8 :                                                 zend_string_release(Z_STR_P(op1));
    2257           8 :                                                 if (lval == ZEND_LONG_MAX) {
    2258             :                                                         /* switch to double */
    2259           0 :                                                         double d = (double)lval;
    2260           0 :                                                         ZVAL_DOUBLE(op1, d+1);
    2261             :                                                 } else {
    2262           8 :                                                         ZVAL_LONG(op1, lval+1);
    2263             :                                                 }
    2264           8 :                                                 break;
    2265             :                                         case IS_DOUBLE:
    2266           6 :                                                 zend_string_release(Z_STR_P(op1));
    2267           6 :                                                 ZVAL_DOUBLE(op1, dval+1);
    2268           6 :                                                 break;
    2269             :                                         default:
    2270             :                                                 /* Perl style string increment */
    2271          55 :                                                 increment_string(op1);
    2272             :                                                 break;
    2273             :                                 }
    2274             :                         }
    2275          69 :                         break;
    2276             :                 case IS_OBJECT:
    2277           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2278           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2279             :                                 /* proxy object */
    2280             :                                 zval rv;
    2281             :                                 zval *val;
    2282             :                                 TSRMLS_FETCH();
    2283             : 
    2284           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv TSRMLS_CC);
    2285             :                                 Z_ADDREF_P(val);
    2286             :                                 fast_increment_function(val);
    2287           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val TSRMLS_CC);
    2288           0 :                                 zval_ptr_dtor(val);
    2289           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2290             :                                 zval op2;
    2291             :                                 int res;
    2292             :                                 TSRMLS_FETCH();
    2293             : 
    2294           2 :                                 ZVAL_LONG(&op2, 1);
    2295           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, &op2 TSRMLS_CC);
    2296           2 :                                 zval_ptr_dtor(&op2);
    2297             : 
    2298           2 :                                 return res;
    2299             :                         }
    2300           1 :                         return FAILURE;
    2301             :                 case IS_REFERENCE:
    2302           0 :                         op1 = Z_REFVAL_P(op1);
    2303           0 :                         goto try_again;
    2304             :                 default:
    2305           0 :                         return FAILURE;
    2306             :         }
    2307       18356 :         return SUCCESS;
    2308             : }
    2309             : /* }}} */
    2310             : 
    2311      292251 : ZEND_API int decrement_function(zval *op1) /* {{{ */
    2312             : {
    2313             :         zend_long lval;
    2314             :         double dval;
    2315             : 
    2316             : try_again:
    2317      292251 :         switch (Z_TYPE_P(op1)) {
    2318             :                 case IS_LONG:
    2319          18 :                         if (Z_LVAL_P(op1) == ZEND_LONG_MIN) {
    2320           0 :                                 double d = (double)Z_LVAL_P(op1);
    2321           0 :                                 ZVAL_DOUBLE(op1, d-1);
    2322             :                         } else {
    2323          18 :                         Z_LVAL_P(op1)--;
    2324             :                         }
    2325          18 :                         break;
    2326             :                 case IS_DOUBLE:
    2327      292192 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
    2328      292192 :                         break;
    2329             :                 case IS_STRING:         /* Like perl we only support string increment */
    2330          33 :                         if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
    2331           1 :                                 zend_string_release(Z_STR_P(op1));
    2332           1 :                                 ZVAL_LONG(op1, -1);
    2333           1 :                                 break;
    2334             :                         }
    2335          64 :                         switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2336             :                                 case IS_LONG:
    2337           8 :                                         zend_string_release(Z_STR_P(op1));
    2338           8 :                                         if (lval == ZEND_LONG_MIN) {
    2339           1 :                                                 double d = (double)lval;
    2340           1 :                                                 ZVAL_DOUBLE(op1, d-1);
    2341             :                                         } else {
    2342           7 :                                                 ZVAL_LONG(op1, lval-1);
    2343             :                                         }
    2344           8 :                                         break;
    2345             :                                 case IS_DOUBLE:
    2346           7 :                                         zend_string_release(Z_STR_P(op1));
    2347           7 :                                         ZVAL_DOUBLE(op1, dval - 1);
    2348             :                                         break;
    2349             :                         }
    2350          32 :                         break;
    2351             :                 case IS_OBJECT:
    2352           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2353           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2354             :                                 /* proxy object */
    2355             :                                 zval rv;
    2356             :                                 zval *val;
    2357             :                                 TSRMLS_FETCH();
    2358             : 
    2359           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv TSRMLS_CC);
    2360             :                                 Z_ADDREF_P(val);
    2361             :                                 fast_decrement_function(val);
    2362           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val TSRMLS_CC);
    2363           0 :                                 zval_ptr_dtor(val);
    2364           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2365             :                                 zval op2;
    2366             :                                 int res;
    2367             :                                 TSRMLS_FETCH();
    2368             : 
    2369           2 :                                 ZVAL_LONG(&op2, 1);
    2370           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, &op2 TSRMLS_CC);
    2371           2 :                                 zval_ptr_dtor(&op2);
    2372             : 
    2373           2 :                                 return res;
    2374             :                         }
    2375           1 :                         return FAILURE;
    2376             :                 case IS_REFERENCE:
    2377           0 :                         op1 = Z_REFVAL_P(op1);
    2378           0 :                         goto try_again;
    2379             :                 default:
    2380           5 :                         return FAILURE;
    2381             :         }
    2382             : 
    2383      292243 :         return SUCCESS;
    2384             : }
    2385             : /* }}} */
    2386             : 
    2387        3487 : ZEND_API int zval_is_true(zval *op) /* {{{ */
    2388             : {
    2389        3487 :         convert_to_boolean(op);
    2390        3487 :         return (Z_TYPE_P(op) == IS_TRUE ? 1 : 0);
    2391             : }
    2392             : /* }}} */
    2393             : 
    2394             : #ifdef ZEND_USE_TOLOWER_L
    2395             : ZEND_API void zend_update_current_locale(void) /* {{{ */
    2396             : {
    2397             :         current_locale = _get_current_locale();
    2398             : }
    2399             : /* }}} */
    2400             : #endif
    2401             : 
    2402   138645335 : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, size_t length) /* {{{ */
    2403             : {
    2404   138645335 :         register unsigned char *str = (unsigned char*)source;
    2405   138645335 :         register unsigned char *result = (unsigned char*)dest;
    2406   138645335 :         register unsigned char *end = str + length;
    2407             : 
    2408  2161598893 :         while (str < end) {
    2409  1884308223 :                 *result++ = zend_tolower_ascii(*str++);
    2410             :         }
    2411   138645335 :         *result = '\0';
    2412             : 
    2413   138645335 :         return dest;
    2414             : }
    2415             : /* }}} */
    2416             : 
    2417     4166373 : ZEND_API char *zend_str_tolower_dup(const char *source, size_t length) /* {{{ */
    2418             : {
    2419     4166373 :         return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
    2420             : }
    2421             : /* }}} */
    2422             : 
    2423       61251 : ZEND_API void zend_str_tolower(char *str, size_t length) /* {{{ */
    2424             : {
    2425       61251 :         register unsigned char *p = (unsigned char*)str;
    2426       61251 :         register unsigned char *end = p + length;
    2427             : 
    2428      548042 :         while (p < end) {
    2429      425540 :                 *p = zend_tolower_ascii(*p);
    2430      425540 :                 p++;
    2431             :         }
    2432       61251 : }
    2433             : /* }}} */
    2434             : 
    2435      922268 : ZEND_API int zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2436             : {
    2437             :         int retval;
    2438             : 
    2439      922268 :         if (s1 == s2) {
    2440         323 :                 return 0;
    2441             :         }
    2442      921945 :         retval = memcmp(s1, s2, MIN(len1, len2));
    2443      921945 :         if (!retval) {
    2444      255384 :                 return (int)(len1 - len2);
    2445             :         } else {
    2446      666561 :                 return retval;
    2447             :         }
    2448             : }
    2449             : /* }}} */
    2450             : 
    2451       14280 : ZEND_API int zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2452             : {
    2453             :         int retval;
    2454             : 
    2455       14280 :         if (s1 == s2) {
    2456          44 :                 return 0;
    2457             :         }
    2458       14236 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    2459       14236 :         if (!retval) {
    2460       13960 :                 return (int)(MIN(length, len1) - MIN(length, len2));
    2461             :         } else {
    2462         276 :                 return retval;
    2463             :         }
    2464             : }
    2465             : /* }}} */
    2466             : 
    2467      445979 : ZEND_API int zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2468             : {
    2469             :         size_t len;
    2470             :         int c1, c2;
    2471             : 
    2472      445979 :         if (s1 == s2) {
    2473         121 :                 return 0;
    2474             :         }
    2475             : 
    2476      445858 :         len = MIN(len1, len2);
    2477     1862711 :         while (len--) {
    2478     1402363 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2479     1402363 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2480     1402363 :                 if (c1 != c2) {
    2481      431368 :                         return c1 - c2;
    2482             :                 }
    2483             :         }
    2484             : 
    2485       14490 :         return (int)(len1 - len2);
    2486             : }
    2487             : /* }}} */
    2488             : 
    2489       20036 : ZEND_API int zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2490             : {
    2491             :         size_t len;
    2492             :         int c1, c2;
    2493             : 
    2494       20036 :         if (s1 == s2) {
    2495          45 :                 return 0;
    2496             :         }
    2497       19991 :         len = MIN(length, MIN(len1, len2));
    2498       47285 :         while (len--) {
    2499        7761 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2500        7761 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2501        7761 :                 if (c1 != c2) {
    2502         458 :                         return c1 - c2;
    2503             :                 }
    2504             :         }
    2505             : 
    2506       19533 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2507             : }
    2508             : /* }}} */
    2509             : 
    2510         109 : ZEND_API int zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2511             : {
    2512             :         size_t len;
    2513             :         int c1, c2;
    2514             : 
    2515         109 :         if (s1 == s2) {
    2516           0 :                 return 0;
    2517             :         }
    2518             : 
    2519         109 :         len = MIN(len1, len2);
    2520         508 :         while (len--) {
    2521         374 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2522         374 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2523         374 :                 if (c1 != c2) {
    2524          84 :                         return c1 - c2;
    2525             :                 }
    2526             :         }
    2527             : 
    2528          25 :         return (int)(len1 - len2);
    2529             : }
    2530             : /* }}} */
    2531             : 
    2532           1 : ZEND_API int zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2533             : {
    2534             :         size_t len;
    2535             :         int c1, c2;
    2536             : 
    2537           1 :         if (s1 == s2) {
    2538           0 :                 return 0;
    2539             :         }
    2540           1 :         len = MIN(length, MIN(len1, len2));
    2541           4 :         while (len--) {
    2542           2 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2543           2 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2544           2 :                 if (c1 != c2) {
    2545           0 :                         return c1 - c2;
    2546             :                 }
    2547             :         }
    2548             : 
    2549           1 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2550             : }
    2551             : /* }}} */
    2552             : 
    2553           2 : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2554             : {
    2555           2 :         return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2556             : }
    2557             : /* }}} */
    2558             : 
    2559           0 : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2560             : {
    2561           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));
    2562             : }
    2563             : /* }}} */
    2564             : 
    2565           0 : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
    2566             : {
    2567           0 :         return zend_binary_strcasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2568             : }
    2569             : /* }}} */
    2570             : 
    2571           0 : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2572             : {
    2573           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));
    2574             : }
    2575             : /* }}} */
    2576             : 
    2577      633903 : ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
    2578             : {
    2579             :         int ret1, ret2;
    2580             :         int oflow1, oflow2;
    2581      633903 :         zend_long lval1 = 0, lval2 = 0;
    2582      633903 :         double dval1 = 0.0, dval2 = 0.0;
    2583             : 
    2584     1880027 :         if ((ret1=is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
    2585      306761 :                 (ret2=is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) {
    2586             : #if ZEND_ULONG_MAX == 0xFFFFFFFF
    2587             :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
    2588             :                         ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
    2589             :                         || (oflow1 == -1 && dval1 < -9007199254740991.))) {
    2590             : #else
    2591      306591 :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
    2592             : #endif
    2593             :                         /* both values are integers overflown to the same side, and the
    2594             :                          * double comparison may have resulted in crucial accuracy lost */
    2595        1124 :                         goto string_cmp;
    2596             :                 }
    2597      405576 :                 if ((ret1==IS_DOUBLE) || (ret2==IS_DOUBLE)) {
    2598      100116 :                         if (ret1!=IS_DOUBLE) {
    2599          27 :                                 if (oflow2) {
    2600             :                                         /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
    2601           3 :                                         ZVAL_LONG(result, -1 * oflow2);
    2602           3 :                                         return;
    2603             :                                 }
    2604          24 :                                 dval1 = (double) lval1;
    2605      100089 :                         } else if (ret2!=IS_DOUBLE) {
    2606          21 :                                 if (oflow1) {
    2607           0 :                                         ZVAL_LONG(result, oflow1);
    2608           0 :                                         return;
    2609             :                                 }
    2610          21 :                                 dval2 = (double) lval2;
    2611      100068 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2612             :                                 /* Both values overflowed and have the same sign,
    2613             :                                  * so a numeric comparison would be inaccurate */
    2614           4 :                                 goto string_cmp;
    2615             :                         }
    2616      100109 :                         Z_DVAL_P(result) = dval1 - dval2;
    2617      100109 :                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    2618             :                 } else { /* they both have to be long's */
    2619      205351 :                         ZVAL_LONG(result, lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0));
    2620             :                 }
    2621             :         } else {
    2622             : string_cmp:
    2623      328440 :                 Z_LVAL_P(result) = zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2624      328440 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_LVAL_P(result)));
    2625             :         }
    2626             : }
    2627             : /* }}} */
    2628             : 
    2629        2568 : static int hash_zval_compare_function(zval *z1, zval *z2 TSRMLS_DC) /* {{{ */
    2630             : {
    2631             :         zval result;
    2632             : 
    2633        2568 :         if (compare_function(&result, z1, z2 TSRMLS_CC)==FAILURE) {
    2634           0 :                 return 1;
    2635             :         }
    2636        2568 :         return Z_LVAL(result);
    2637             : }
    2638             : /* }}} */
    2639             : 
    2640         299 : ZEND_API int zend_compare_symbol_tables_i(HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2641             : {
    2642         299 :         return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC);
    2643             : }
    2644             : /* }}} */
    2645             : 
    2646         758 : ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC) /* {{{ */
    2647             : {
    2648         758 :         ZVAL_LONG(result, ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0 TSRMLS_CC));
    2649         758 : }
    2650             : /* }}} */
    2651             : 
    2652         753 : ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC) /* {{{ */
    2653             : {
    2654         753 :         zend_compare_symbol_tables(result, Z_ARRVAL_P(a1), Z_ARRVAL_P(a2) TSRMLS_CC);
    2655         753 : }
    2656             : /* }}} */
    2657             : 
    2658           1 : ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
    2659             : {
    2660           1 :         if (Z_OBJ_P(o1) == Z_OBJ_P(o2)) {
    2661           1 :                 ZVAL_LONG(result, 0);
    2662           1 :                 return;
    2663             :         }
    2664             : 
    2665           0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2666           0 :                 ZVAL_LONG(result, 1);
    2667             :         } else {
    2668           0 :                 ZVAL_LONG(result, Z_OBJ_HT_P(o1)->compare_objects(o1, o2 TSRMLS_CC));
    2669             :         }
    2670             : }
    2671             : /* }}} */
    2672             : 
    2673           0 : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
    2674             : {
    2675             :         zend_string *str;
    2676             :         TSRMLS_FETCH();
    2677             : 
    2678           0 :         str = zend_strpprintf(0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
    2679           0 :         ZVAL_NEW_STR(op, str);
    2680           0 : }
    2681             : /* }}} */
    2682             : 
    2683      501661 : ZEND_API zend_string *zend_long_to_str(zend_long num) /* {{{ */
    2684             : {
    2685             :         char buf[MAX_LENGTH_OF_LONG + 1];
    2686      501661 :         char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
    2687     1003322 :         return zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
    2688             : }
    2689             : /* }}} */
    2690             : 
    2691         505 : ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval) {
    2692        1010 :     return is_numeric_string_ex(str->val, str->len, lval, dval, -1, NULL);
    2693             : }
    2694             : 
    2695      963219 : ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
    2696             : {
    2697             :         const char *ptr;
    2698      963219 :         int base = 10, digits = 0, dp_or_e = 0;
    2699      963219 :         double local_dval = 0.0;
    2700             :         zend_uchar type;
    2701             : 
    2702      963219 :         if (!length) {
    2703        1472 :                 return 0;
    2704             :         }
    2705             : 
    2706      961747 :         if (oflow_info != NULL) {
    2707      827474 :                 *oflow_info = 0;
    2708             :         }
    2709             : 
    2710             :         /* Skip any whitespace
    2711             :          * This is much faster than the isspace() function */
    2712     1925260 :         while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
    2713        1766 :                 str++;
    2714        1766 :                 length--;
    2715             :         }
    2716      961747 :         ptr = str;
    2717             : 
    2718      961747 :         if (*ptr == '-' || *ptr == '+') {
    2719        2456 :                 ptr++;
    2720             :         }
    2721             : 
    2722     1517829 :         if (ZEND_IS_DIGIT(*ptr)) {
    2723             :                 /* Handle hex numbers
    2724             :                  * str is used instead of ptr to disallow signs and keep old behavior */
    2725      761374 :                 if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
    2726         236 :                         base = 16;
    2727         236 :                         ptr += 2;
    2728             :                 }
    2729             : 
    2730             :                 /* Skip any leading 0s */
    2731     1788730 :                 while (*ptr == '0') {
    2732      265982 :                         ptr++;
    2733             :                 }
    2734             : 
    2735             :                 /* Count the number of digits. If a decimal point/exponent is found,
    2736             :                  * it's a double. Otherwise, if there's a dval or no need to check for
    2737             :                  * a full match, stop when there are too many digits for a long */
    2738    10882824 :                 for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
    2739             : check_digits:
    2740     5439170 :                         if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
    2741     4680038 :                                 continue;
    2742      759132 :                         } else if (base == 10) {
    2743      758896 :                                 if (*ptr == '.' && dp_or_e < 1) {
    2744             :                                         goto process_double;
    2745      556163 :                                 } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
    2746         358 :                                         const char *e = ptr + 1;
    2747             : 
    2748         358 :                                         if (*e == '-' || *e == '+') {
    2749           9 :                                                 ptr = e++;
    2750             :                                         }
    2751         358 :                                         if (ZEND_IS_DIGIT(*e)) {
    2752         315 :                                                 goto process_double;
    2753             :                                         }
    2754             :                                 }
    2755             :                         }
    2756             : 
    2757      556084 :                         break;
    2758             :                 }
    2759             : 
    2760      558346 :                 if (base == 10) {
    2761      558110 :                         if (digits >= MAX_LENGTH_OF_LONG) {
    2762        2264 :                                 if (oflow_info != NULL) {
    2763        2259 :                                         *oflow_info = *str == '-' ? -1 : 1;
    2764             :                                 }
    2765        2264 :                                 dp_or_e = -1;
    2766        2264 :                                 goto process_double;
    2767             :                         }
    2768         236 :                 } else if (!(digits < SIZEOF_ZEND_LONG * 2 || (digits == SIZEOF_ZEND_LONG * 2 && ptr[-digits] <= '7'))) {
    2769           0 :                         if (dval) {
    2770           0 :                                 local_dval = zend_hex_strtod(str, &ptr);
    2771             :                         }
    2772           0 :                         if (oflow_info != NULL) {
    2773           0 :                                 *oflow_info = 1;
    2774             :                         }
    2775           0 :                         type = IS_DOUBLE;
    2776             :                 }
    2777      405885 :         } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
    2778             : process_double:
    2779      205532 :                 type = IS_DOUBLE;
    2780             : 
    2781             :                 /* If there's a dval, do the conversion; else continue checking
    2782             :                  * the digits if we need to check for a full match */
    2783      205532 :                 if (dval) {
    2784      205510 :                         local_dval = zend_strtod(str, &ptr);
    2785          22 :                 } else if (allow_errors != 1 && dp_or_e != -1) {
    2786          20 :                         dp_or_e = (*ptr++ == '.') ? 1 : 2;
    2787          20 :                         goto check_digits;
    2788             :                 }
    2789             :         } else {
    2790      200153 :                 return 0;
    2791             :         }
    2792             : 
    2793      761594 :         if (ptr != str + length) {
    2794       14857 :                 if (!allow_errors) {
    2795       14026 :                         return 0;
    2796             :                 }
    2797         831 :                 if (allow_errors == -1) {
    2798          58 :                         zend_error(E_NOTICE, "A non well formed numeric value encountered");
    2799             :                 }
    2800             :         }
    2801             : 
    2802      747568 :         if (type == IS_LONG) {
    2803      542828 :                 if (digits == MAX_LENGTH_OF_LONG - 1) {
    2804         149 :                         int cmp = strcmp(&ptr[-digits], long_min_digits);
    2805             : 
    2806         149 :                         if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
    2807           3 :                                 if (dval) {
    2808           3 :                                         *dval = zend_strtod(str, NULL);
    2809             :                                 }
    2810           3 :                                 if (oflow_info != NULL) {
    2811           3 :                                         *oflow_info = *str == '-' ? -1 : 1;
    2812             :                                 }
    2813             : 
    2814           3 :                                 return IS_DOUBLE;
    2815             :                         }
    2816             :                 }
    2817             : 
    2818      542825 :                 if (lval) {
    2819      542764 :                         *lval = ZEND_STRTOL(str, NULL, base);
    2820             :                 }
    2821             : 
    2822      542825 :                 return IS_LONG;
    2823             :         } else {
    2824      204740 :                 if (dval) {
    2825      204722 :                         *dval = local_dval;
    2826             :                 }
    2827             : 
    2828      204740 :                 return IS_DOUBLE;
    2829             :         }
    2830             : }
    2831             : 
    2832             : /*
    2833             :  * Local variables:
    2834             :  * tab-width: 4
    2835             :  * c-basic-offset: 4
    2836             :  * indent-tabs-mode: t
    2837             :  * End:
    2838             :  */

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:10 +0000 (9 days ago)

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