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: 1189 1393 85.4 %
Date: 2016-09-18 Functions: 77 88 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2016 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             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #include <ctype.h>
      24             : 
      25             : #include "zend.h"
      26             : #include "zend_operators.h"
      27             : #include "zend_variables.h"
      28             : #include "zend_globals.h"
      29             : #include "zend_list.h"
      30             : #include "zend_API.h"
      31             : #include "zend_strtod.h"
      32             : #include "zend_exceptions.h"
      33             : #include "zend_closures.h"
      34             : 
      35             : #if ZEND_USE_TOLOWER_L
      36             : #include <locale.h>
      37             : static _locale_t current_locale = NULL;
      38             : /* this is true global! may lead to strange effects on ZTS, but so may setlocale() */
      39             : #define zend_tolower(c) _tolower_l(c, current_locale)
      40             : #else
      41             : #define zend_tolower(c) tolower(c)
      42             : #endif
      43             : 
      44             : #define TYPE_PAIR(t1,t2) (((t1) << 4) | (t2))
      45             : 
      46             : static const unsigned char tolower_map[256] = {
      47             : 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
      48             : 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
      49             : 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
      50             : 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
      51             : 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
      52             : 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x5e,0x5f,
      53             : 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
      54             : 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
      55             : 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
      56             : 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
      57             : 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
      58             : 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
      59             : 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
      60             : 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
      61             : 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
      62             : 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
      63             : };
      64             : 
      65             : #define zend_tolower_ascii(c) (tolower_map[(unsigned char)(c)])
      66             : 
      67             : /**
      68             :  * Functions using locale lowercase:
      69             :                 zend_binary_strncasecmp_l
      70             :                 zend_binary_strcasecmp_l
      71             :                 zend_binary_zval_strcasecmp
      72             :                 zend_binary_zval_strncasecmp
      73             :                 string_compare_function_ex
      74             :                 string_case_compare_function
      75             :  * Functions using ascii lowercase:
      76             :                 zend_str_tolower_copy
      77             :                 zend_str_tolower_dup
      78             :                 zend_str_tolower
      79             :                 zend_binary_strcasecmp
      80             :                 zend_binary_strncasecmp
      81             :  */
      82             : 
      83       72265 : ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, int str_len) /* {{{ */
      84             : {
      85             :         int retval;
      86             : 
      87       72265 :         if (!str_len) {
      88       47807 :                 str_len = (int)strlen(str);
      89             :         }
      90       72265 :         retval = ZEND_STRTOL(str, NULL, 0);
      91       72265 :         if (str_len>0) {
      92       48370 :                 switch (str[str_len-1]) {
      93             :                         case 'g':
      94             :                         case 'G':
      95           0 :                                 retval *= 1024;
      96             :                                 /* break intentionally missing */
      97             :                         case 'm':
      98             :                         case 'M':
      99           0 :                                 retval *= 1024;
     100             :                                 /* break intentionally missing */
     101             :                         case 'k':
     102             :                         case 'K':
     103           0 :                                 retval *= 1024;
     104             :                                 break;
     105             :                 }
     106             :         }
     107       72265 :         return retval;
     108             : }
     109             : /* }}} */
     110             : 
     111     1530037 : ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, int str_len) /* {{{ */
     112             : {
     113             :         zend_long retval;
     114             : 
     115     1530037 :         if (!str_len) {
     116       23765 :                 str_len = (int)strlen(str);
     117             :         }
     118     1530037 :         retval = ZEND_STRTOL(str, NULL, 0);
     119     1530037 :         if (str_len>0) {
     120     1506272 :                 switch (str[str_len-1]) {
     121             :                         case 'g':
     122             :                         case 'G':
     123           4 :                                 retval *= 1024;
     124             :                                 /* break intentionally missing */
     125             :                         case 'm':
     126             :                         case 'M':
     127       71727 :                                 retval *= 1024;
     128             :                                 /* break intentionally missing */
     129             :                         case 'k':
     130             :                         case 'K':
     131       95650 :                                 retval *= 1024;
     132             :                                 break;
     133             :                 }
     134             :         }
     135     1530037 :         return retval;
     136             : }
     137             : /* }}} */
     138             : 
     139      203367 : void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{ */
     140             : {
     141             : try_again:
     142      203367 :         switch (Z_TYPE_P(op)) {
     143             :                 case IS_REFERENCE:
     144             :                         zend_unwrap_reference(op);
     145           4 :                         goto try_again;
     146             :                 case IS_STRING:
     147             :                         {
     148             :                                 zend_string *str;
     149             : 
     150      101129 :                                 str = Z_STR_P(op);
     151      202258 :                                 if ((Z_TYPE_INFO_P(op)=is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &Z_LVAL_P(op), &Z_DVAL_P(op), silent ? 1 : -1)) == 0) {
     152          54 :                                         ZVAL_LONG(op, 0);
     153          54 :                                         if (!silent) {
     154           6 :                                                 zend_error(E_WARNING, "A non-numeric value encountered");
     155             :                                         }
     156             :                                 }
     157             :                                 zend_string_release(str);
     158      101129 :                                 break;
     159             :                         }
     160             :                 case IS_NULL:
     161             :                 case IS_FALSE:
     162          62 :                         ZVAL_LONG(op, 0);
     163          62 :                         break;
     164             :                 case IS_TRUE:
     165          16 :                         ZVAL_LONG(op, 1);
     166          16 :                         break;
     167             :                 case IS_RESOURCE:
     168             :                         {
     169           5 :                                 zend_long l = Z_RES_HANDLE_P(op);
     170           5 :                                 zval_ptr_dtor(op);
     171           5 :                                 ZVAL_LONG(op, l);
     172             :                         }
     173           5 :                         break;
     174             :                 case IS_OBJECT:
     175           6 :                         convert_to_long_base(op, 10);
     176             :                         break;
     177             :         }
     178      203363 : }
     179             : /* }}} */
     180             : 
     181      203318 : ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
     182             : {
     183      203318 :         _convert_scalar_to_number(op, 1);
     184      203318 : }
     185             : /* }}} */
     186             : 
     187             : /* {{{ zendi_convert_scalar_to_number */
     188             : #define zendi_convert_scalar_to_number(op, holder, result, silent)      \
     189             :         if (op==result) {                                                                                               \
     190             :                 if (Z_TYPE_P(op) != IS_LONG) {                                                          \
     191             :                         _convert_scalar_to_number(op, silent);                          \
     192             :                 }                                                                                                                       \
     193             :         } else {                                                                                                                \
     194             :                 switch (Z_TYPE_P(op)) {                                                                         \
     195             :                         case IS_STRING:                                                                                 \
     196             :                                 {                                                                                                       \
     197             :                                         if ((Z_TYPE_INFO(holder)=is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &Z_LVAL(holder), &Z_DVAL(holder), silent ? 1 : -1)) == 0) {  \
     198             :                                                 ZVAL_LONG(&(holder), 0);                                                    \
     199             :                                                 if (!silent) {                                                                          \
     200             :                                                         zend_error(E_WARNING, "A non-numeric value encountered");     \
     201             :                                                 }                                                                                                       \
     202             :                                         }                                                                                                               \
     203             :                                         (op) = &(holder);                                                                           \
     204             :                                         break;                                                                                                  \
     205             :                                 }                                                                                                                       \
     206             :                         case IS_NULL:                                                                                                   \
     207             :                         case IS_FALSE:                                                                                                  \
     208             :                                 ZVAL_LONG(&(holder), 0);                                                                    \
     209             :                                 (op) = &(holder);                                                                                   \
     210             :                                 break;                                                                                                          \
     211             :                         case IS_TRUE:                                                                                                   \
     212             :                                 ZVAL_LONG(&(holder), 1);                                                                    \
     213             :                                 (op) = &(holder);                                                                                   \
     214             :                                 break;                                                                                                          \
     215             :                         case IS_RESOURCE:                                                                                               \
     216             :                                 ZVAL_LONG(&(holder), Z_RES_HANDLE_P(op));                                   \
     217             :                                 (op) = &(holder);                                                                                   \
     218             :                                 break;                                                                                                          \
     219             :                         case IS_OBJECT:                                                                                                 \
     220             :                                 ZVAL_COPY(&(holder), op);                                                                           \
     221             :                                 convert_to_long_base(&(holder), 10);                                                \
     222             :                                 if (Z_TYPE(holder) == IS_LONG) {                                                        \
     223             :                                         (op) = &(holder);                                                                           \
     224             :                                 }                                                                                                                       \
     225             :                                 break;                                                                                                          \
     226             :                 }                                                                                                                                       \
     227             :         }
     228             : 
     229             : /* }}} */
     230             : 
     231             : /* {{{ convert_object_to_type: dst will be either ctype or UNDEF */
     232             : #define convert_object_to_type(op, dst, ctype, conv_func)                                                                       \
     233             :         ZVAL_UNDEF(dst);                                                                                                                                                \
     234             :         if (Z_OBJ_HT_P(op)->cast_object) {                                                                                                           \
     235             :                 if (Z_OBJ_HT_P(op)->cast_object(op, dst, ctype) == FAILURE) {                                \
     236             :                         zend_error(E_RECOVERABLE_ERROR,                                                                                                 \
     237             :                                 "Object of class %s could not be converted to %s", ZSTR_VAL(Z_OBJCE_P(op)->name),\
     238             :                         zend_get_type_by_const(ctype));                                                                                                 \
     239             :                 }                                                                                                                                                                       \
     240             :         } else if (Z_OBJ_HT_P(op)->get) {                                                                                                            \
     241             :                 zval *newop = Z_OBJ_HT_P(op)->get(op, dst);                                                          \
     242             :                 if (Z_TYPE_P(newop) != IS_OBJECT) {                                                                                                     \
     243             :                         /* for safety - avoid loop */                                                                                                   \
     244             :                         ZVAL_COPY_VALUE(dst, newop);                                                                                                    \
     245             :                         conv_func(dst);                                                                                                                                 \
     246             :                 }                                                                                                                                                                       \
     247             :         }
     248             : 
     249             : /* }}} */
     250             : 
     251             : #define convert_op1_op2_long(op1, op1_lval, op2, op2_lval, op, op_func) \
     252             :         do {                                                                                                                            \
     253             :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {                                             \
     254             :                         if (Z_ISREF_P(op1)) {                                                                           \
     255             :                                 op1 = Z_REFVAL_P(op1);                                                                  \
     256             :                                 if (Z_TYPE_P(op1) == IS_LONG) {                                                 \
     257             :                                         op1_lval = Z_LVAL_P(op1);                                                       \
     258             :                                         break;                                                                                          \
     259             :                                 }                                                                                                               \
     260             :                         }                                                                                                                       \
     261             :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(op, op_func);                      \
     262             :                         op1_lval = _zval_get_long_func_noisy(op1);                                      \
     263             :                 } else {                                                                                                                \
     264             :                         op1_lval = Z_LVAL_P(op1);                                                                       \
     265             :                 }                                                                                                                               \
     266             :         } while (0);                                                                                                            \
     267             :         do {                                                                                                                            \
     268             :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {                                             \
     269             :                         if (Z_ISREF_P(op2)) {                                                                           \
     270             :                                 op2 = Z_REFVAL_P(op2);                                                                  \
     271             :                                 if (Z_TYPE_P(op2) == IS_LONG) {                                                 \
     272             :                                         op2_lval = Z_LVAL_P(op2);                                                       \
     273             :                                         break;                                                                                          \
     274             :                                 }                                                                                                               \
     275             :                         }                                                                                                                       \
     276             :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(op);                                       \
     277             :                         op2_lval = _zval_get_long_func_noisy(op2);                                      \
     278             :                 } else {                                                                                                                \
     279             :                         op2_lval = Z_LVAL_P(op2);                                                                       \
     280             :                 }                                                                                                                               \
     281             :         } while (0);
     282             : 
     283       22083 : ZEND_API void ZEND_FASTCALL convert_to_long(zval *op) /* {{{ */
     284             : {
     285       22083 :         if (Z_TYPE_P(op) != IS_LONG) {
     286         493 :                 convert_to_long_base(op, 10);
     287             :         }
     288       22083 : }
     289             : /* }}} */
     290             : 
     291         506 : ZEND_API void ZEND_FASTCALL convert_to_long_base(zval *op, int base) /* {{{ */
     292             : {
     293             :         zend_long tmp;
     294             : 
     295             : try_again:
     296         506 :         switch (Z_TYPE_P(op)) {
     297             :                 case IS_NULL:
     298             :                 case IS_FALSE:
     299         126 :                         ZVAL_LONG(op, 0);
     300         126 :                         break;
     301             :                 case IS_TRUE:
     302          37 :                         ZVAL_LONG(op, 1);
     303          37 :                         break;
     304             :                 case IS_RESOURCE:
     305          11 :                         tmp = Z_RES_HANDLE_P(op);
     306          11 :                         zval_ptr_dtor(op);
     307          11 :                         ZVAL_LONG(op, tmp);
     308          11 :                         break;
     309             :                 case IS_LONG:
     310           0 :                         break;
     311             :                 case IS_DOUBLE:
     312         214 :                         ZVAL_LONG(op, zend_dval_to_lval(Z_DVAL_P(op)));
     313         107 :                         break;
     314             :                 case IS_STRING:
     315             :                         {
     316         164 :                                 zend_string *str = Z_STR_P(op);
     317         164 :                                 if (base == 10) {
     318         328 :                                         ZVAL_LONG(op, zval_get_long(op));
     319             :                                 } else {
     320           0 :                                         ZVAL_LONG(op, ZEND_STRTOL(ZSTR_VAL(str), NULL, base));
     321             :                                 }
     322             :                                 zend_string_release(str);
     323             :                         }
     324         164 :                         break;
     325             :                 case IS_ARRAY:
     326          34 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     327          34 :                         zval_ptr_dtor(op);
     328          34 :                         ZVAL_LONG(op, tmp);
     329          34 :                         break;
     330             :                 case IS_OBJECT:
     331             :                         {
     332             :                                 zval dst;
     333             : 
     334          27 :                                 convert_object_to_type(op, &dst, IS_LONG, convert_to_long);
     335             :                                 zval_dtor(op);
     336             : 
     337          27 :                                 if (Z_TYPE(dst) == IS_LONG) {
     338          27 :                                         ZVAL_COPY_VALUE(op, &dst);
     339             :                                 } else {
     340             : 
     341           0 :                                         ZVAL_LONG(op, 1);
     342             :                                 }
     343          27 :                                 return;
     344             :                         }
     345             :                 case IS_REFERENCE:
     346             :                         zend_unwrap_reference(op);
     347           0 :                         goto try_again;
     348             :                 EMPTY_SWITCH_DEFAULT_CASE()
     349             :         }
     350             : }
     351             : /* }}} */
     352             : 
     353        3158 : ZEND_API void ZEND_FASTCALL convert_to_double(zval *op) /* {{{ */
     354             : {
     355             :         double tmp;
     356             : 
     357             : try_again:
     358        3158 :         switch (Z_TYPE_P(op)) {
     359             :                 case IS_NULL:
     360             :                 case IS_FALSE:
     361           9 :                         ZVAL_DOUBLE(op, 0.0);
     362           9 :                         break;
     363             :                 case IS_TRUE:
     364           1 :                         ZVAL_DOUBLE(op, 1.0);
     365           1 :                         break;
     366             :                 case IS_RESOURCE: {
     367           7 :                                 double d = (double) Z_RES_HANDLE_P(op);
     368           7 :                                 zval_ptr_dtor(op);
     369           7 :                                 ZVAL_DOUBLE(op, d);
     370             :                         }
     371           7 :                         break;
     372             :                 case IS_LONG:
     373        1948 :                         ZVAL_DOUBLE(op, (double) Z_LVAL_P(op));
     374        1948 :                         break;
     375             :                 case IS_DOUBLE:
     376        1013 :                         break;
     377             :                 case IS_STRING:
     378             :                         {
     379         168 :                                 zend_string *str = Z_STR_P(op);
     380             : 
     381         168 :                                 ZVAL_DOUBLE(op, zend_strtod(ZSTR_VAL(str), NULL));
     382             :                                 zend_string_release(str);
     383             :                         }
     384         168 :                         break;
     385             :                 case IS_ARRAY:
     386           8 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     387           8 :                         zval_ptr_dtor(op);
     388           8 :                         ZVAL_DOUBLE(op, tmp);
     389           8 :                         break;
     390             :                 case IS_OBJECT:
     391             :                         {
     392             :                                 zval dst;
     393             : 
     394           4 :                                 convert_object_to_type(op, &dst, IS_DOUBLE, convert_to_double);
     395             :                                 zval_dtor(op);
     396             : 
     397           4 :                                 if (Z_TYPE(dst) == IS_DOUBLE) {
     398           4 :                                         ZVAL_COPY_VALUE(op, &dst);
     399             :                                 } else {
     400           0 :                                         ZVAL_DOUBLE(op, 1.0);
     401             :                                 }
     402           4 :                                 break;
     403             :                         }
     404             :                 case IS_REFERENCE:
     405             :                         zend_unwrap_reference(op);
     406           0 :                         goto try_again;
     407             :                 EMPTY_SWITCH_DEFAULT_CASE()
     408             :         }
     409        3158 : }
     410             : /* }}} */
     411             : 
     412         914 : ZEND_API void ZEND_FASTCALL convert_to_null(zval *op) /* {{{ */
     413             : {
     414         914 :         zval_ptr_dtor(op);
     415         914 :         ZVAL_NULL(op);
     416         914 : }
     417             : /* }}} */
     418             : 
     419         360 : ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */
     420             : {
     421             :         int tmp;
     422             : 
     423             : try_again:
     424         360 :         switch (Z_TYPE_P(op)) {
     425             :                 case IS_FALSE:
     426             :                 case IS_TRUE:
     427         233 :                         break;
     428             :                 case IS_NULL:
     429           5 :                         ZVAL_FALSE(op);
     430           5 :                         break;
     431             :                 case IS_RESOURCE: {
     432           7 :                                 zend_long l = (Z_RES_HANDLE_P(op) ? 1 : 0);
     433             : 
     434           7 :                                 zval_ptr_dtor(op);
     435           7 :                                 ZVAL_BOOL(op, l);
     436             :                         }
     437           7 :                         break;
     438             :                 case IS_LONG:
     439          79 :                         ZVAL_BOOL(op, Z_LVAL_P(op) ? 1 : 0);
     440          79 :                         break;
     441             :                 case IS_DOUBLE:
     442           6 :                         ZVAL_BOOL(op, Z_DVAL_P(op) ? 1 : 0);
     443           6 :                         break;
     444             :                 case IS_STRING:
     445             :                         {
     446          17 :                                 zend_string *str = Z_STR_P(op);
     447             : 
     448          37 :                                 if (ZSTR_LEN(str) == 0
     449          36 :                                         || (ZSTR_LEN(str) == 1 && ZSTR_VAL(str)[0] == '0')) {
     450           1 :                                         ZVAL_FALSE(op);
     451             :                                 } else {
     452          16 :                                         ZVAL_TRUE(op);
     453             :                                 }
     454             :                                 zend_string_release(str);
     455             :                         }
     456          17 :                         break;
     457             :                 case IS_ARRAY:
     458           8 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     459           8 :                         zval_ptr_dtor(op);
     460           8 :                         ZVAL_BOOL(op, tmp);
     461           8 :                         break;
     462             :                 case IS_OBJECT:
     463             :                         {
     464             :                                 zval dst;
     465             : 
     466           5 :                                 convert_object_to_type(op, &dst, _IS_BOOL, convert_to_boolean);
     467             :                                 zval_dtor(op);
     468             : 
     469          15 :                                 if (Z_TYPE(dst) == IS_FALSE || Z_TYPE(dst) == IS_TRUE) {
     470           5 :                                         ZVAL_COPY_VALUE(op, &dst);
     471             :                                 } else {
     472           0 :                                         ZVAL_TRUE(op);
     473             :                                 }
     474           5 :                                 break;
     475             :                         }
     476             :                 case IS_REFERENCE:
     477             :                         zend_unwrap_reference(op);
     478           0 :                         goto try_again;
     479             :                 EMPTY_SWITCH_DEFAULT_CASE()
     480             :         }
     481         360 : }
     482             : /* }}} */
     483             : 
     484          13 : ZEND_API void ZEND_FASTCALL _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     485             : {
     486          13 :         if (Z_TYPE_P(op) == IS_DOUBLE) {
     487             :                 zend_string *str;
     488           1 :                 double dval = Z_DVAL_P(op);
     489             : 
     490           1 :                 str = zend_strpprintf(0, "%.*H", (int) EG(precision), dval);
     491           1 :                 ZVAL_NEW_STR(op, str);
     492             :         } else {
     493          12 :                 _convert_to_string(op ZEND_FILE_LINE_CC);
     494             :         }
     495          13 : }
     496             : /* }}} */
     497             : 
     498       72620 : ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     499             : {
     500             : try_again:
     501       72620 :         switch (Z_TYPE_P(op)) {
     502             :                 case IS_UNDEF:
     503             :                 case IS_NULL:
     504             :                 case IS_FALSE: {
     505        4270 :                         ZVAL_EMPTY_STRING(op);
     506        4270 :                         break;
     507             :                 }
     508             :                 case IS_TRUE:
     509         785 :                         if (CG(one_char_string)['1']) {
     510           0 :                                 ZVAL_INTERNED_STR(op, CG(one_char_string)['1']);
     511             :                         } else {
     512        1570 :                                 ZVAL_NEW_STR(op, zend_string_init("1", 1, 0));
     513             :                         }
     514         785 :                         break;
     515             :                 case IS_STRING:
     516           3 :                         break;
     517             :                 case IS_RESOURCE: {
     518             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     519          43 :                         int len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
     520          43 :                         zval_ptr_dtor(op);
     521          86 :                         ZVAL_NEW_STR(op, zend_string_init(buf, len, 0));
     522          43 :                         break;
     523             :                 }
     524             :                 case IS_LONG: {
     525       65337 :                         ZVAL_NEW_STR(op, zend_long_to_str(Z_LVAL_P(op)));
     526       65337 :                         break;
     527             :                 }
     528             :                 case IS_DOUBLE: {
     529             :                         zend_string *str;
     530        1968 :                         double dval = Z_DVAL_P(op);
     531             : 
     532        1968 :                         str = zend_strpprintf(0, "%.*G", (int) EG(precision), dval);
     533             :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     534        1968 :                         ZVAL_NEW_STR(op, str);
     535        1968 :                         break;
     536             :                 }
     537             :                 case IS_ARRAY:
     538         168 :                         zend_error(E_NOTICE, "Array to string conversion");
     539         168 :                         zval_ptr_dtor(op);
     540         336 :                         ZVAL_NEW_STR(op, zend_string_init("Array", sizeof("Array")-1, 0));
     541         168 :                         break;
     542             :                 case IS_OBJECT: {
     543             :                         zval dst;
     544             : 
     545          43 :                         convert_object_to_type(op, &dst, IS_STRING, convert_to_string);
     546             :                         zval_dtor(op);
     547             : 
     548          35 :                         if (Z_TYPE(dst) == IS_STRING) {
     549          30 :                                 ZVAL_COPY_VALUE(op, &dst);
     550             :                         } else {
     551          10 :                                 ZVAL_NEW_STR(op, zend_string_init("Object", sizeof("Object")-1, 0));
     552             :                         }
     553          35 :                         break;
     554             :                 }
     555             :                 case IS_REFERENCE:
     556             :                         zend_unwrap_reference(op);
     557           3 :                         goto try_again;
     558             :                 EMPTY_SWITCH_DEFAULT_CASE()
     559             :         }
     560       72609 : }
     561             : /* }}} */
     562             : 
     563         120 : static void convert_scalar_to_array(zval *op) /* {{{ */
     564             : {
     565             :         zval entry;
     566             : 
     567         120 :         ZVAL_COPY_VALUE(&entry, op);
     568             : 
     569         120 :         ZVAL_NEW_ARR(op);
     570         120 :         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     571         120 :         zend_hash_index_add_new(Z_ARRVAL_P(op), 0, &entry);
     572         120 : }
     573             : /* }}} */
     574             : 
     575         218 : ZEND_API void ZEND_FASTCALL convert_to_array(zval *op) /* {{{ */
     576             : {
     577             : try_again:
     578         218 :         switch (Z_TYPE_P(op)) {
     579             :                 case IS_ARRAY:
     580          50 :                         break;
     581             : /* OBJECTS_OPTIMIZE */
     582             :                 case IS_OBJECT:
     583          30 :                         if (Z_OBJCE_P(op) == zend_ce_closure) {
     584           3 :                                 convert_scalar_to_array(op);
     585             :                         } else {
     586          27 :                                 if (Z_OBJ_HT_P(op)->get_properties) {
     587          27 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op);
     588          27 :                                         if (obj_ht) {
     589             :                                                 zend_array *arr;
     590             : 
     591          82 :                                                 if (!Z_OBJCE_P(op)->default_properties_count &&
     592          22 :                                                         obj_ht == Z_OBJ_P(op)->properties &&
     593          17 :                                                         !ZEND_HASH_GET_APPLY_COUNT(Z_OBJ_P(op)->properties)) {
     594             :                                                         /* fast copy */
     595          16 :                                                         if (EXPECTED(Z_OBJ_P(op)->handlers == &std_object_handlers)) {
     596          14 :                                                                 arr = obj_ht;
     597          14 :                                                                 if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(op)->properties) & IS_ARRAY_IMMUTABLE))) {
     598          14 :                                                                         GC_REFCOUNT(Z_OBJ_P(op)->properties)++;
     599             :                                                                 }
     600             :                                                         } else {
     601           2 :                                                                 arr = zend_array_dup(obj_ht);
     602             :                                                         }
     603             :                                                         zval_dtor(op);
     604          16 :                                                         ZVAL_ARR(op, arr);
     605             :                                                 } else {
     606          11 :                                                         arr = zend_array_dup(obj_ht);
     607             :                                                         zval_dtor(op);
     608          11 :                                                         ZVAL_ARR(op, arr);
     609             :                                                 }
     610          27 :                                                 return;
     611             :                                         }
     612             :                                 } else {
     613             :                                         zval dst;
     614           0 :                                         convert_object_to_type(op, &dst, IS_ARRAY, convert_to_array);
     615             : 
     616           0 :                                         if (Z_TYPE(dst) == IS_ARRAY) {
     617             :                                                 zval_dtor(op);
     618           0 :                                                 ZVAL_COPY_VALUE(op, &dst);
     619           0 :                                                 return;
     620             :                                         }
     621             :                                 }
     622             : 
     623             :                                 zval_dtor(op);
     624           0 :                                 array_init(op);
     625             :                         }
     626           3 :                         break;
     627             :                 case IS_NULL:
     628          21 :                         ZVAL_NEW_ARR(op);
     629          21 :                         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     630          21 :                         break;
     631             :                 case IS_REFERENCE:
     632             :                         zend_unwrap_reference(op);
     633           0 :                         goto try_again;
     634             :                 default:
     635         117 :                         convert_scalar_to_array(op);
     636             :                         break;
     637             :         }
     638             : }
     639             : /* }}} */
     640             : 
     641         157 : ZEND_API void ZEND_FASTCALL convert_to_object(zval *op) /* {{{ */
     642             : {
     643             : try_again:
     644         157 :         switch (Z_TYPE_P(op)) {
     645             :                 case IS_ARRAY:
     646             :                         {
     647         113 :                                 HashTable *ht = Z_ARR_P(op);
     648         113 :                                 if (Z_IMMUTABLE_P(op)) {
     649             :                                         /* TODO: try not to duplicate immutable arrays as well ??? */
     650           0 :                                         ht = zend_array_dup(ht);
     651             :                                 }
     652         113 :                                 object_and_properties_init(op, zend_standard_class_def, ht);
     653         113 :                                 break;
     654             :                         }
     655             :                 case IS_OBJECT:
     656           3 :                         break;
     657             :                 case IS_NULL:
     658           3 :                         object_init(op);
     659           3 :                         break;
     660             :                 case IS_REFERENCE:
     661             :                         zend_unwrap_reference(op);
     662           0 :                         goto try_again;
     663             :                 default: {
     664             :                         zval tmp;
     665          38 :                         ZVAL_COPY_VALUE(&tmp, op);
     666          38 :                         object_init(op);
     667          38 :                         zend_hash_add_new(Z_OBJPROP_P(op), CG(known_strings)[ZEND_STR_SCALAR], &tmp);
     668             :                         break;
     669             :                 }
     670             :         }
     671         157 : }
     672             : /* }}} */
     673             : 
     674           0 : ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
     675             : {
     676             :         zval *arg;
     677             :         va_list ap;
     678             : 
     679           0 :         va_start(ap, argc);
     680             : 
     681           0 :         while (argc--) {
     682           0 :                 arg = va_arg(ap, zval *);
     683           0 :                 convert_to_long_ex(arg);
     684             :         }
     685             : 
     686           0 :         va_end(ap);
     687           0 : }
     688             : /* }}} */
     689             : 
     690           0 : ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
     691             : {
     692             :         zval *arg;
     693             :         va_list ap;
     694             : 
     695           0 :         va_start(ap, argc);
     696             : 
     697           0 :         while (argc--) {
     698           0 :                 arg = va_arg(ap, zval *);
     699           0 :                 convert_to_double_ex(arg);
     700             :         }
     701             : 
     702           0 :         va_end(ap);
     703           0 : }
     704             : /* }}} */
     705             : 
     706           0 : ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
     707             : {
     708             :         zval *arg;
     709             :         va_list ap;
     710             : 
     711           0 :         va_start(ap, argc);
     712             : 
     713           0 :         while (argc--) {
     714           0 :                 arg = va_arg(ap, zval *);
     715           0 :                 convert_to_string_ex(arg);
     716             :         }
     717             : 
     718           0 :         va_end(ap);
     719           0 : }
     720             : /* }}} */
     721             : 
     722             : static zend_always_inline zend_long ZEND_FASTCALL _zval_get_long_func_ex(zval *op, zend_bool silent) /* {{{ */
     723             : {
     724             : try_again:
     725       16646 :         switch (Z_TYPE_P(op)) {
     726             :                 case IS_UNDEF:
     727             :                 case IS_NULL:
     728             :                 case IS_FALSE:
     729        1013 :                         return 0;
     730             :                 case IS_TRUE:
     731        3169 :                         return 1;
     732             :                 case IS_RESOURCE:
     733         108 :                         return Z_RES_HANDLE_P(op);
     734             :                 case IS_LONG:
     735           1 :                         return Z_LVAL_P(op);
     736             :                 case IS_DOUBLE:
     737        7364 :                         return zend_dval_to_lval(Z_DVAL_P(op));
     738             :                 case IS_STRING:
     739             :                         {
     740             :                                 zend_uchar type;
     741             :                                 zend_long lval;
     742             :                                 double dval;
     743       15594 :                                 if (0 == (type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval, silent ? 1 : -1))) {
     744        1204 :                                         if (!silent) {
     745         200 :                                                 zend_error(E_WARNING, "A non-numeric value encountered");
     746             :                                         }
     747        1204 :                                         return 0;
     748        6593 :                                 } else if (EXPECTED(type == IS_LONG)) {
     749        6102 :                                         return lval;
     750             :                                 } else {
     751             :                                         /* Previously we used strtol here, not is_numeric_string,
     752             :                                          * and strtol gives you LONG_MAX/_MIN on overflow.
     753             :                                          * We use use saturating conversion to emulate strtol()'s
     754             :                                          * behaviour.
     755             :                                          */
     756         982 :                                          return zend_dval_to_lval_cap(dval);
     757             :                                 }
     758             :                         }
     759             :                 case IS_ARRAY:
     760         844 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1 : 0;
     761             :                 case IS_OBJECT:
     762             :                         {
     763             :                                 zval dst;
     764          26 :                                 convert_object_to_type(op, &dst, IS_LONG, convert_to_long);
     765          26 :                                 if (Z_TYPE(dst) == IS_LONG) {
     766          26 :                                         return Z_LVAL(dst);
     767             :                                 } else {
     768           0 :                                         return 1;
     769             :                                 }
     770             :                         }
     771             :                 case IS_REFERENCE:
     772           6 :                         op = Z_REFVAL_P(op);
     773             :                         goto try_again;
     774             :                 EMPTY_SWITCH_DEFAULT_CASE()
     775             :         }
     776           0 :         return 0;
     777             : }
     778             : /* }}} */
     779             : 
     780       14866 : ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op) /* {{{ */
     781             : {
     782       14866 :         return _zval_get_long_func_ex(op, 1);
     783             : }
     784             : /* }}} */
     785             : 
     786        1774 : static zend_long ZEND_FASTCALL _zval_get_long_func_noisy(zval *op) /* {{{ */
     787             : {
     788        1774 :         return _zval_get_long_func_ex(op, 0);
     789             : }
     790             : /* }}} */
     791             : 
     792        5083 : ZEND_API double ZEND_FASTCALL _zval_get_double_func(zval *op) /* {{{ */
     793             : {
     794             : try_again:
     795        5083 :         switch (Z_TYPE_P(op)) {
     796             :                 case IS_NULL:
     797             :                 case IS_FALSE:
     798         106 :                         return 0.0;
     799             :                 case IS_TRUE:
     800         113 :                         return 1.0;
     801             :                 case IS_RESOURCE:
     802          41 :                         return (double) Z_RES_HANDLE_P(op);
     803             :                 case IS_LONG:
     804        3823 :                         return (double) Z_LVAL_P(op);
     805             :                 case IS_DOUBLE:
     806           0 :                         return Z_DVAL_P(op);
     807             :                 case IS_STRING:
     808         621 :                         return zend_strtod(Z_STRVAL_P(op), NULL);
     809             :                 case IS_ARRAY:
     810         357 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1.0 : 0.0;
     811             :                 case IS_OBJECT:
     812             :                         {
     813             :                                 zval dst;
     814          10 :                                 convert_object_to_type(op, &dst, IS_DOUBLE, convert_to_double);
     815             : 
     816          10 :                                 if (Z_TYPE(dst) == IS_DOUBLE) {
     817          10 :                                         return Z_DVAL(dst);
     818             :                                 } else {
     819           0 :                                         return 1.0;
     820             :                                 }
     821             :                         }
     822             :                 case IS_REFERENCE:
     823          12 :                         op = Z_REFVAL_P(op);
     824          12 :                         goto try_again;
     825             :                 EMPTY_SWITCH_DEFAULT_CASE()
     826             :         }
     827           0 :         return 0.0;
     828             : }
     829             : /* }}} */
     830             : 
     831     2935399 : ZEND_API zend_string* ZEND_FASTCALL _zval_get_string_func(zval *op) /* {{{ */
     832             : {
     833             : try_again:
     834     2935399 :         switch (Z_TYPE_P(op)) {
     835             :                 case IS_UNDEF:
     836             :                 case IS_NULL:
     837             :                 case IS_FALSE:
     838     1375135 :                         return ZSTR_EMPTY_ALLOC();
     839             :                 case IS_TRUE:
     840        1375 :                         if (CG(one_char_string)['1']) {
     841           0 :                                 return CG(one_char_string)['1'];
     842             :                         } else {
     843        1375 :                                 return zend_string_init("1", 1, 0);
     844             :                         }
     845             :                 case IS_RESOURCE: {
     846             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     847             :                         int len;
     848             : 
     849         642 :                         len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
     850        1284 :                         return zend_string_init(buf, len, 0);
     851             :                 }
     852             :                 case IS_LONG: {
     853      418951 :                         return zend_long_to_str(Z_LVAL_P(op));
     854             :                 }
     855             :                 case IS_DOUBLE: {
     856        6014 :                         return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
     857             :                 }
     858             :                 case IS_ARRAY:
     859         770 :                         zend_error(E_NOTICE, "Array to string conversion");
     860         770 :                         return zend_string_init("Array", sizeof("Array")-1, 0);
     861             :                 case IS_OBJECT: {
     862             :                         zval tmp;
     863      103731 :                         if (Z_OBJ_HT_P(op)->cast_object) {
     864      103731 :                                 if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_STRING) == SUCCESS) {
     865      103692 :                                         return Z_STR(tmp);
     866             :                                 }
     867           0 :                         } else if (Z_OBJ_HT_P(op)->get) {
     868           0 :                                 zval *z = Z_OBJ_HT_P(op)->get(op, &tmp);
     869           0 :                                 if (Z_TYPE_P(z) != IS_OBJECT) {
     870           0 :                                         zend_string *str = zval_get_string(z);
     871           0 :                                         zval_ptr_dtor(z);
     872           0 :                                         return str;
     873             :                                 }
     874           0 :                                 zval_ptr_dtor(z);
     875             :                         }
     876          34 :                         zend_error(EG(exception) ? E_ERROR : E_RECOVERABLE_ERROR, "Object of class %s could not be converted to string", ZSTR_VAL(Z_OBJCE_P(op)->name));
     877          29 :                         return ZSTR_EMPTY_ALLOC();
     878             :                 }
     879             :                 case IS_REFERENCE:
     880      522694 :                         op = Z_REFVAL_P(op);
     881      522694 :                         goto try_again;
     882             :                 case IS_STRING:
     883     1012174 :                         return zend_string_copy(Z_STR_P(op));
     884             :                 EMPTY_SWITCH_DEFAULT_CASE()
     885             :         }
     886           0 :         return NULL;
     887             : }
     888             : /* }}} */
     889             : 
     890     1728387 : ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {{{ */
     891             : {
     892             :         zval op1_copy, op2_copy;
     893     1728387 :         int converted = 0;
     894             : 
     895             :         while (1) {
     896     3457790 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     897             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
     898             :                                 fast_long_add_function(result, op1, op2);
     899      780963 :                                 return SUCCESS;
     900             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     901          57 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     902          57 :                                 return SUCCESS;
     903             : 
     904             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     905          62 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     906          62 :                                 return SUCCESS;
     907             : 
     908             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     909      947262 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     910      947262 :                                 return SUCCESS;
     911             : 
     912             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
     913          31 :                                 if ((result == op1) && (result == op2)) {
     914             :                                         /* $a += $a */
     915           1 :                                         return SUCCESS;
     916             :                                 }
     917          30 :                                 if (result != op1) {
     918          28 :                                         ZVAL_DUP(result, op1);
     919             :                                 }
     920          30 :                                 zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0);
     921          30 :                                 return SUCCESS;
     922             : 
     923             :                         default:
     924         520 :                                 if (Z_ISREF_P(op1)) {
     925          24 :                                         op1 = Z_REFVAL_P(op1);
     926         496 :                                 } else if (Z_ISREF_P(op2)) {
     927          18 :                                         op2 = Z_REFVAL_P(op2);
     928         478 :                                 } else if (!converted) {
     929        1407 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function);
     930             : 
     931        1253 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
     932        1174 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
     933         466 :                                         converted = 1;
     934             :                                 } else {
     935           8 :                                         zend_throw_error(NULL, "Unsupported operand types");
     936           8 :                                         return FAILURE; /* unknown datatype */
     937             :                                 }
     938             :                 }
     939         508 :         }
     940             : }
     941             : /* }}} */
     942             : 
     943     2898378 : ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {{{ */
     944             : {
     945             :         zval op1_copy, op2_copy;
     946     2898378 :         int converted = 0;
     947             : 
     948             :         while (1) {
     949    17163814 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     950             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
     951             :                                 fast_long_sub_function(result, op1, op2);
     952     2898144 :                                 return SUCCESS;
     953             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     954          57 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     955          57 :                                 return SUCCESS;
     956             : 
     957             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     958          50 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     959          50 :                                 return SUCCESS;
     960             : 
     961             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     962         119 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     963         119 :                                 return SUCCESS;
     964             : 
     965             :                         default:
     966     5683537 :                                 if (Z_ISREF_P(op1)) {
     967     2841608 :                                         op1 = Z_REFVAL_P(op1);
     968     2841929 :                                 } else if (Z_ISREF_P(op2)) {
     969     2841607 :                                         op2 = Z_REFVAL_P(op2);
     970         322 :                                 } else if (!converted) {
     971         951 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function);
     972             : 
     973         847 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
     974         921 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
     975         314 :                                         converted = 1;
     976             :                                 } else {
     977           4 :                                         zend_throw_error(NULL, "Unsupported operand types");
     978           2 :                                         return FAILURE; /* unknown datatype */
     979             :                                 }
     980             :                 }
     981     5683529 :         }
     982             : }
     983             : /* }}} */
     984             : 
     985        7409 : ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* {{{ */
     986             : {
     987             :         zval op1_copy, op2_copy;
     988        7409 :         int converted = 0;
     989             : 
     990             :         while (1) {
     991       15320 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     992             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     993             :                                 zend_long overflow;
     994             : 
     995        5521 :                                 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
     996        5521 :                                 Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
     997        5521 :                                 return SUCCESS;
     998             : 
     999             :                         }
    1000             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1001        1779 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
    1002        1779 :                                 return SUCCESS;
    1003             : 
    1004             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1005          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
    1006          61 :                                 return SUCCESS;
    1007             : 
    1008             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1009          39 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
    1010          39 :                                 return SUCCESS;
    1011             : 
    1012             :                         default:
    1013         260 :                                 if (Z_ISREF_P(op1)) {
    1014           4 :                                         op1 = Z_REFVAL_P(op1);
    1015         256 :                                 } else if (Z_ISREF_P(op2)) {
    1016           4 :                                         op2 = Z_REFVAL_P(op2);
    1017         252 :                                 } else if (!converted) {
    1018         747 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function);
    1019             : 
    1020         707 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
    1021         706 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
    1022         243 :                                         converted = 1;
    1023             :                                 } else {
    1024           2 :                                         zend_throw_error(NULL, "Unsupported operand types");
    1025           2 :                                         return FAILURE; /* unknown datatype */
    1026             :                                 }
    1027             :                 }
    1028         251 :         }
    1029             : }
    1030             : /* }}} */
    1031             : 
    1032     2843838 : ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1033             : {
    1034             :         zval op1_copy, op2_copy;
    1035     2843838 :         int converted = 0;
    1036             : 
    1037             :         while (1) {
    1038     5687824 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1039             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1040     2843120 :                                 if (Z_LVAL_P(op2) >= 0) {
    1041     2842437 :                                         zend_long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
    1042             : 
    1043     2842437 :                                         if (i == 0) {
    1044          28 :                                                 ZVAL_LONG(result, 1L);
    1045          28 :                                                 return SUCCESS;
    1046     2842409 :                                         } else if (l2 == 0) {
    1047     2841614 :                                                 ZVAL_LONG(result, 0);
    1048     2841614 :                                                 return SUCCESS;
    1049             :                                         }
    1050             : 
    1051        6679 :                                         while (i >= 1) {
    1052             :                                                 zend_long overflow;
    1053        5181 :                                                 double dval = 0.0;
    1054             : 
    1055        5181 :                                                 if (i % 2) {
    1056        2013 :                                                         --i;
    1057        2013 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
    1058        2013 :                                                         if (overflow) {
    1059          17 :                                                                 ZVAL_DOUBLE(result, dval * pow(l2, i));
    1060          17 :                                                                 return SUCCESS;
    1061             :                                                         }
    1062             :                                                 } else {
    1063        3168 :                                                         i /= 2;
    1064        3168 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
    1065        3168 :                                                         if (overflow) {
    1066          75 :                                                                 ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
    1067          75 :                                                                 return SUCCESS;
    1068             :                                                         }
    1069             :                                                 }
    1070             :                                         }
    1071             :                                         /* i == 0 */
    1072         703 :                                         ZVAL_LONG(result, l1);
    1073             :                                 } else {
    1074         683 :                                         ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
    1075             :                                 }
    1076        1386 :                                 return SUCCESS;
    1077             : 
    1078             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1079         501 :                                 ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
    1080         501 :                                 return SUCCESS;
    1081             : 
    1082             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1083         147 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
    1084         147 :                                 return SUCCESS;
    1085             : 
    1086             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1087          65 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
    1088          65 :                                 return SUCCESS;
    1089             : 
    1090             :                         default:
    1091          79 :                                 if (Z_ISREF_P(op1)) {
    1092           0 :                                         op1 = Z_REFVAL_P(op1);
    1093          79 :                                 } else if (Z_ISREF_P(op2)) {
    1094           1 :                                         op2 = Z_REFVAL_P(op2);
    1095          78 :                                 } else if (!converted) {
    1096         232 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW, pow_function);
    1097             : 
    1098          75 :                                         if (Z_TYPE_P(op1) == IS_ARRAY) {
    1099           1 :                                                 ZVAL_LONG(result, 0);
    1100           1 :                                                 return SUCCESS;
    1101             :                                         } else {
    1102         195 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
    1103             :                                         }
    1104          74 :                                         if (Z_TYPE_P(op2) == IS_ARRAY) {
    1105           1 :                                                 ZVAL_LONG(result, 1L);
    1106           1 :                                                 return SUCCESS;
    1107             :                                         } else {
    1108         156 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
    1109             :                                         }
    1110          73 :                                         converted = 1;
    1111             :                                 } else {
    1112           0 :                                         zend_throw_error(NULL, "Unsupported operand types");
    1113           0 :                                         return FAILURE;
    1114             :                                 }
    1115             :                 }
    1116          74 :         }
    1117             : }
    1118             : /* }}} */
    1119             : 
    1120      131262 : ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1121             : {
    1122             :         zval op1_copy, op2_copy;
    1123      131262 :         int converted = 0;
    1124             : 
    1125             :         while (1) {
    1126      263124 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1127             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1128      121650 :                                 if (Z_LVAL_P(op2) == 0) {
    1129          47 :                                         zend_error(E_WARNING, "Division by zero");
    1130          47 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1) / (double) Z_LVAL_P(op2)));
    1131          47 :                                         return SUCCESS;
    1132      121603 :                                 } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN) {
    1133             :                                         /* Prevent overflow error/crash */
    1134           1 :                                         ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
    1135           1 :                                         return SUCCESS;
    1136             :                                 }
    1137      121602 :                                 if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
    1138       79627 :                                         ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
    1139             :                                 } else {
    1140       41975 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
    1141             :                                 }
    1142      121602 :                                 return SUCCESS;
    1143             : 
    1144             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1145        9391 :                                 if (Z_LVAL_P(op2) == 0) {
    1146          17 :                                         zend_error(E_WARNING, "Division by zero");
    1147             :                                 }
    1148        9391 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
    1149        9391 :                                 return SUCCESS;
    1150             : 
    1151             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1152          72 :                                 if (Z_DVAL_P(op2) == 0) {
    1153           1 :                                         zend_error(E_WARNING, "Division by zero");
    1154             :                                 }
    1155          72 :                                 ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
    1156          72 :                                 return SUCCESS;
    1157             : 
    1158             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1159         143 :                                 if (Z_DVAL_P(op2) == 0) {
    1160           1 :                                         zend_error(E_WARNING, "Division by zero");
    1161             :                                 }
    1162         143 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
    1163         143 :                                 return SUCCESS;
    1164             : 
    1165             :                         default:
    1166         306 :                                 if (Z_ISREF_P(op1)) {
    1167           0 :                                         op1 = Z_REFVAL_P(op1);
    1168         306 :                                 } else if (Z_ISREF_P(op2)) {
    1169           7 :                                         op2 = Z_REFVAL_P(op2);
    1170         299 :                                 } else if (!converted) {
    1171         888 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function);
    1172             : 
    1173         873 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
    1174         787 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
    1175         293 :                                         converted = 1;
    1176             :                                 } else {
    1177           2 :                                         zend_throw_error(NULL, "Unsupported operand types");
    1178           2 :                                         return FAILURE; /* unknown datatype */
    1179             :                                 }
    1180             :                 }
    1181         300 :         }
    1182             : }
    1183             : /* }}} */
    1184             : 
    1185         404 : ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1186             : {
    1187             :         zend_long op1_lval, op2_lval;
    1188             : 
    1189        2595 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function);
    1190             : 
    1191         400 :         if (op1 == result) {
    1192             :                 zval_dtor(result);
    1193             :         }
    1194             : 
    1195         400 :         if (op2_lval == 0) {
    1196             :                 /* modulus by zero */
    1197          98 :                 if (EG(current_execute_data) && !CG(in_compilation)) {
    1198          49 :                         zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
    1199             :                 } else {
    1200           0 :                         zend_error_noreturn(E_ERROR, "Modulo by zero");
    1201             :                 }
    1202          49 :                 ZVAL_UNDEF(result);
    1203          49 :                 return FAILURE;
    1204             :         }
    1205             : 
    1206         351 :         if (op2_lval == -1) {
    1207             :                 /* Prevent overflow error/crash if op1==LONG_MIN */
    1208           6 :                 ZVAL_LONG(result, 0);
    1209           6 :                 return SUCCESS;
    1210             :         }
    1211             : 
    1212         345 :         ZVAL_LONG(result, op1_lval % op2_lval);
    1213         345 :         return SUCCESS;
    1214             : }
    1215             : /* }}} */
    1216             : 
    1217           2 : ZEND_API int ZEND_FASTCALL boolean_xor_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1218             : {
    1219             :         int op1_val, op2_val;
    1220             : 
    1221             :         do {
    1222           2 :                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1223           0 :                         op1_val = 0;
    1224           2 :                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1225           0 :                         op1_val = 1;
    1226             :                 } else {
    1227           2 :                         if (Z_ISREF_P(op1)) {
    1228           0 :                                 op1 = Z_REFVAL_P(op1);
    1229           0 :                                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1230           0 :                                         op1_val = 0;
    1231           0 :                                         break;
    1232           0 :                                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1233           0 :                                         op1_val = 1;
    1234           0 :                                         break;
    1235             :                                 }
    1236             :                         }
    1237           4 :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BOOL_XOR, boolean_xor_function);
    1238           2 :                         op1_val = zval_is_true(op1);
    1239             :                 }
    1240             :         } while (0);
    1241             :         do {
    1242           2 :                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1243           0 :                         op2_val = 0;
    1244           2 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1245           0 :                         op2_val = 1;
    1246             :                 } else {
    1247           2 :                         if (Z_ISREF_P(op2)) {
    1248           0 :                                 op2 = Z_REFVAL_P(op2);
    1249           0 :                                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1250           0 :                                         op2_val = 0;
    1251           0 :                                         break;
    1252           0 :                                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1253           0 :                                         op2_val = 1;
    1254           0 :                                         break;
    1255             :                                 }
    1256             :                         }
    1257           2 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BOOL_XOR);
    1258           2 :                         op2_val = zval_is_true(op2);
    1259             :                 }
    1260             :         } while (0);
    1261             : 
    1262           2 :         ZVAL_BOOL(result, op1_val ^ op2_val);
    1263           2 :         return SUCCESS;
    1264             : }
    1265             : /* }}} */
    1266             : 
    1267         424 : ZEND_API int ZEND_FASTCALL boolean_not_function(zval *result, zval *op1) /* {{{ */
    1268             : {
    1269         424 :         if (Z_TYPE_P(op1) < IS_TRUE) {
    1270           9 :                 ZVAL_TRUE(result);
    1271         415 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1272         351 :                 ZVAL_FALSE(result);
    1273             :         } else {
    1274          64 :                 if (Z_ISREF_P(op1)) {
    1275           0 :                         op1 = Z_REFVAL_P(op1);
    1276           0 :                         if (Z_TYPE_P(op1) < IS_TRUE) {
    1277           0 :                                 ZVAL_TRUE(result);
    1278           0 :                                 return SUCCESS;
    1279           0 :                         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1280           0 :                                 ZVAL_FALSE(result);
    1281           0 :                                 return SUCCESS;
    1282             :                         }
    1283             :                 }
    1284          64 :                 ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
    1285             : 
    1286          64 :                 ZVAL_BOOL(result, !zval_is_true(op1));
    1287             :         }
    1288         424 :         return SUCCESS;
    1289             : }
    1290             : /* }}} */
    1291             : 
    1292         121 : ZEND_API int ZEND_FASTCALL bitwise_not_function(zval *result, zval *op1) /* {{{ */
    1293             : {
    1294             : try_again:
    1295         121 :         switch (Z_TYPE_P(op1)) {
    1296             :                 case IS_LONG:
    1297          97 :                         ZVAL_LONG(result, ~Z_LVAL_P(op1));
    1298          97 :                         return SUCCESS;
    1299             :                 case IS_DOUBLE:
    1300           6 :                         ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
    1301           3 :                         return SUCCESS;
    1302             :                 case IS_STRING: {
    1303             :                         size_t i;
    1304             : 
    1305          18 :                         if (Z_STRLEN_P(op1) == 1) {
    1306           3 :                                 zend_uchar not = (zend_uchar) ~*Z_STRVAL_P(op1);
    1307           3 :                                 if (CG(one_char_string)[not]) {
    1308           2 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[not]);
    1309             :                                 } else {
    1310           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &not, 1, 0));
    1311             :                                 }
    1312             :                         } else {
    1313          30 :                                 ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0));
    1314          85 :                                 for (i = 0; i < Z_STRLEN_P(op1); i++) {
    1315          70 :                                         Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
    1316             :                                 }
    1317          15 :                                 Z_STRVAL_P(result)[i] = 0;
    1318             :                         }
    1319          18 :                         return SUCCESS;
    1320             :                 }
    1321             :                 case IS_REFERENCE:
    1322           0 :                         op1 = Z_REFVAL_P(op1);
    1323           0 :                         goto try_again;
    1324             :                 default:
    1325           3 :                         ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
    1326             : 
    1327           2 :                         zend_throw_error(NULL, "Unsupported operand types");
    1328           2 :                         return FAILURE;
    1329             :         }
    1330             : }
    1331             : /* }}} */
    1332             : 
    1333        1174 : ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1334             : {
    1335             :         zend_long op1_lval, op2_lval;
    1336             : 
    1337        2116 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1338         858 :                 ZVAL_LONG(result, Z_LVAL_P(op1) | Z_LVAL_P(op2));
    1339         858 :                 return SUCCESS;
    1340             :         }
    1341             : 
    1342         316 :         ZVAL_DEREF(op1);
    1343         316 :         ZVAL_DEREF(op2);
    1344             : 
    1345         527 :         if (Z_TYPE_P(op1) == IS_STRING && EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1346             :                 zval *longer, *shorter;
    1347             :                 zend_string *str;
    1348             :                 size_t i;
    1349             : 
    1350         200 :                 if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
    1351         117 :                         if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
    1352           1 :                                 zend_uchar or = (zend_uchar) (*Z_STRVAL_P(op1) | *Z_STRVAL_P(op2));
    1353           1 :                                 if (CG(one_char_string)[or]) {
    1354           0 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[or]);
    1355             :                                 } else {
    1356           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &or, 1, 0));
    1357             :                                 }
    1358           1 :                                 return SUCCESS;
    1359             :                         }
    1360         116 :                         longer = op1;
    1361         116 :                         shorter = op2;
    1362             :                 } else {
    1363          83 :                         longer = op2;
    1364          83 :                         shorter = op1;
    1365             :                 }
    1366             : 
    1367         398 :                 str = zend_string_alloc(Z_STRLEN_P(longer), 0);
    1368         886 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1369         687 :                         ZSTR_VAL(str)[i] = Z_STRVAL_P(longer)[i] | Z_STRVAL_P(shorter)[i];
    1370             :                 }
    1371         199 :                 memcpy(ZSTR_VAL(str) + i, Z_STRVAL_P(longer) + i, Z_STRLEN_P(longer) - i + 1);
    1372         199 :                 if (result==op1) {
    1373           1 :                         zend_string_release(Z_STR_P(result));
    1374             :                 }
    1375         199 :                 ZVAL_NEW_STR(result, str);
    1376         199 :                 return SUCCESS;
    1377             :         }
    1378             : 
    1379         116 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1380          64 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
    1381          30 :                 op1_lval = _zval_get_long_func_noisy(op1);
    1382             :         } else {
    1383          84 :                 op1_lval = Z_LVAL_P(op1);
    1384             :         }
    1385         114 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1386          24 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
    1387          23 :                 op2_lval = _zval_get_long_func_noisy(op2);
    1388             :         } else {
    1389          90 :                 op2_lval = Z_LVAL_P(op2);
    1390             :         }
    1391             : 
    1392         113 :         if (op1 == result) {
    1393             :                 zval_dtor(result);
    1394             :         }
    1395         113 :         ZVAL_LONG(result, op1_lval | op2_lval);
    1396         113 :         return SUCCESS;
    1397             : }
    1398             : /* }}} */
    1399             : 
    1400         345 : ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1401             : {
    1402             :         zend_long op1_lval, op2_lval;
    1403             : 
    1404         450 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1405          79 :                 ZVAL_LONG(result, Z_LVAL_P(op1) & Z_LVAL_P(op2));
    1406          79 :                 return SUCCESS;
    1407             :         }
    1408             : 
    1409         266 :         ZVAL_DEREF(op1);
    1410         266 :         ZVAL_DEREF(op2);
    1411             : 
    1412         474 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1413             :                 zval *longer, *shorter;
    1414             :                 zend_string *str;
    1415             :                 size_t i;
    1416             : 
    1417         201 :                 if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
    1418         117 :                         if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
    1419           1 :                                 zend_uchar and = (zend_uchar) (*Z_STRVAL_P(op1) & *Z_STRVAL_P(op2));
    1420           1 :                                 if (CG(one_char_string)[and]) {
    1421           0 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[and]);
    1422             :                                 } else {
    1423           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &and, 1, 0));
    1424             :                                 }
    1425           1 :                                 return SUCCESS;
    1426             :                         }
    1427         116 :                         longer = op1;
    1428         116 :                         shorter = op2;
    1429             :                 } else {
    1430          84 :                         longer = op2;
    1431          84 :                         shorter = op1;
    1432             :                 }
    1433             : 
    1434         400 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1435         886 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1436         686 :                         ZSTR_VAL(str)[i] = Z_STRVAL_P(shorter)[i] & Z_STRVAL_P(longer)[i];
    1437             :                 }
    1438         200 :                 ZSTR_VAL(str)[i] = 0;
    1439         200 :                 if (result==op1) {
    1440           1 :                         zend_string_release(Z_STR_P(result));
    1441             :                 }
    1442         200 :                 ZVAL_NEW_STR(result, str);
    1443         200 :                 return SUCCESS;
    1444             :         }
    1445             : 
    1446          65 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1447          78 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
    1448          37 :                 op1_lval = _zval_get_long_func_noisy(op1);
    1449             :         } else {
    1450          26 :                 op1_lval = Z_LVAL_P(op1);
    1451             :         }
    1452          63 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1453          31 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
    1454          30 :                 op2_lval = _zval_get_long_func_noisy(op2);
    1455             :         } else {
    1456          32 :                 op2_lval = Z_LVAL_P(op2);
    1457             :         }
    1458             : 
    1459          62 :         if (op1 == result) {
    1460             :                 zval_dtor(result);
    1461             :         }
    1462          62 :         ZVAL_LONG(result, op1_lval & op2_lval);
    1463          62 :         return SUCCESS;
    1464             : }
    1465             : /* }}} */
    1466             : 
    1467        2313 : ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1468             : {
    1469             :         zend_long op1_lval, op2_lval;
    1470             : 
    1471        4393 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1472        2057 :                 ZVAL_LONG(result, Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
    1473        2057 :                 return SUCCESS;
    1474             :         }
    1475             : 
    1476         256 :         ZVAL_DEREF(op1);
    1477         256 :         ZVAL_DEREF(op2);
    1478             : 
    1479         465 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1480             :                 zval *longer, *shorter;
    1481             :                 zend_string *str;
    1482             :                 size_t i;
    1483             : 
    1484         202 :                 if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
    1485         118 :                         if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
    1486           1 :                                 zend_uchar xor = (zend_uchar) (*Z_STRVAL_P(op1) ^ *Z_STRVAL_P(op2));
    1487           1 :                                 if (CG(one_char_string)[xor]) {
    1488           0 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[xor]);
    1489             :                                 } else {
    1490           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &xor, 1, 0));
    1491             :                                 }
    1492           1 :                                 return SUCCESS;
    1493             :                         }
    1494         117 :                         longer = op1;
    1495         117 :                         shorter = op2;
    1496             :                 } else {
    1497          84 :                         longer = op2;
    1498          84 :                         shorter = op1;
    1499             :                 }
    1500             : 
    1501         402 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1502         890 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1503         689 :                         ZSTR_VAL(str)[i] = Z_STRVAL_P(shorter)[i] ^ Z_STRVAL_P(longer)[i];
    1504             :                 }
    1505         201 :                 ZSTR_VAL(str)[i] = 0;
    1506         201 :                 if (result==op1) {
    1507           1 :                         zend_string_release(Z_STR_P(result));
    1508             :                 }
    1509         201 :                 ZVAL_NEW_STR(result, str);
    1510         201 :                 return SUCCESS;
    1511             :         }
    1512             : 
    1513          54 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1514          62 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
    1515          29 :                 op1_lval = _zval_get_long_func_noisy(op1);
    1516             :         } else {
    1517          23 :                 op1_lval = Z_LVAL_P(op1);
    1518             :         }
    1519          52 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1520          27 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
    1521          26 :                 op2_lval = _zval_get_long_func_noisy(op2);
    1522             :         } else {
    1523          25 :                 op2_lval = Z_LVAL_P(op2);
    1524             :         }
    1525             : 
    1526          51 :         if (op1 == result) {
    1527             :                 zval_dtor(result);
    1528             :         }
    1529          51 :         ZVAL_LONG(result, op1_lval ^ op2_lval);
    1530          51 :         return SUCCESS;
    1531             : }
    1532             : /* }}} */
    1533             : 
    1534        1463 : ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1535             : {
    1536             :         zend_long op1_lval, op2_lval;
    1537             : 
    1538        6060 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function);
    1539             : 
    1540         458 :         if (op1 == result) {
    1541             :                 zval_dtor(result);
    1542             :         }
    1543             : 
    1544             :         /* prevent wrapping quirkiness on some processors where << 64 + x == << x */
    1545         458 :         if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
    1546         338 :                 if (EXPECTED(op2_lval > 0)) {
    1547         216 :                         ZVAL_LONG(result, 0);
    1548         216 :                         return SUCCESS;
    1549             :                 } else {
    1550         244 :                         if (EG(current_execute_data) && !CG(in_compilation)) {
    1551         122 :                                 zend_throw_exception_ex(zend_ce_arithmetic_error, 0, "Bit shift by negative number");
    1552             :                         } else {
    1553           0 :                                 zend_error_noreturn(E_ERROR, "Bit shift by negative number");
    1554             :                         }
    1555         122 :                         ZVAL_UNDEF(result);
    1556         122 :                         return FAILURE;
    1557             :                 }
    1558             :         }
    1559             : 
    1560         120 :         ZVAL_LONG(result, op1_lval << op2_lval);
    1561         120 :         return SUCCESS;
    1562             : }
    1563             : /* }}} */
    1564             : 
    1565         581 : ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1566             : {
    1567             :         zend_long op1_lval, op2_lval;
    1568             : 
    1569        2292 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function);
    1570             : 
    1571         578 :         if (op1 == result) {
    1572             :                 zval_dtor(result);
    1573             :         }
    1574             : 
    1575             :         /* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
    1576         578 :         if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
    1577         338 :                 if (EXPECTED(op2_lval > 0)) {
    1578         216 :                         ZVAL_LONG(result, (op1_lval < 0) ? -1 : 0);
    1579         216 :                         return SUCCESS;
    1580             :                 } else {
    1581         244 :                         if (EG(current_execute_data) && !CG(in_compilation)) {
    1582         122 :                                 zend_throw_exception_ex(zend_ce_arithmetic_error, 0, "Bit shift by negative number");
    1583             :                         } else {
    1584           0 :                                 zend_error_noreturn(E_ERROR, "Bit shift by negative number");
    1585             :                         }
    1586         122 :                         ZVAL_UNDEF(result);
    1587         122 :                         return FAILURE;
    1588             :                 }
    1589             :         }
    1590             : 
    1591         240 :         ZVAL_LONG(result, op1_lval >> op2_lval);
    1592         240 :         return SUCCESS;
    1593             : }
    1594             : /* }}} */
    1595             : 
    1596     8273071 : ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1597             : {
    1598             :         zval op1_copy, op2_copy;
    1599     8273071 :         int use_copy1 = 0, use_copy2 = 0;
    1600             : 
    1601             :         do {
    1602     8273071 :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) {
    1603       51290 :                         if (Z_ISREF_P(op1)) {
    1604       19379 :                                 op1 = Z_REFVAL_P(op1);
    1605       19379 :                                 if (Z_TYPE_P(op1) == IS_STRING) break;
    1606             :                         }
    1607       95743 :                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
    1608       31918 :                         use_copy1 = zend_make_printable_zval(op1, &op1_copy);
    1609       31918 :                         if (use_copy1) {
    1610             :                                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1611             :                                  * we have to free it.
    1612             :                                  */
    1613       31918 :                                 if (result == op1) {
    1614             :                                         zval_dtor(op1);
    1615           9 :                                         if (UNEXPECTED(op1 == op2)) {
    1616           0 :                                                 op2 = &op1_copy;
    1617             :                                         }
    1618             :                                 }
    1619       31918 :                                 op1 = &op1_copy;
    1620             :                         }
    1621             :                 }
    1622             :         } while (0);
    1623             :         do {
    1624     8273071 :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) {
    1625     1478709 :                         if (Z_ISREF_P(op2)) {
    1626        1628 :                                 op2 = Z_REFVAL_P(op2);
    1627        1628 :                                 if (Z_TYPE_P(op2) == IS_STRING) break;
    1628             :                         }
    1629     1478599 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT);
    1630     1478599 :                         use_copy2 = zend_make_printable_zval(op2, &op2_copy);
    1631     1478599 :                         if (use_copy2) {
    1632     1478599 :                                 op2 = &op2_copy;
    1633             :                         }
    1634             :                 }
    1635             :         } while (0);
    1636             : 
    1637             :         {
    1638     8273071 :                 size_t op1_len = Z_STRLEN_P(op1);
    1639     8273071 :                 size_t op2_len = Z_STRLEN_P(op2);
    1640     8273071 :                 size_t result_len = op1_len + op2_len;
    1641             :                 zend_string *result_str;
    1642             : 
    1643     8273071 :                 if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) {
    1644           0 :                         zend_throw_error(NULL, "String size overflow");
    1645           0 :                         ZVAL_FALSE(result);
    1646           0 :                         return FAILURE;
    1647             :                 }
    1648             : 
    1649    15337624 :                 if (result == op1 && Z_REFCOUNTED_P(result)) {
    1650             :                         /* special case, perform operations on result */
    1651    14129106 :                         result_str = zend_string_extend(Z_STR_P(result), result_len, 0);
    1652             :                 } else {
    1653     1208518 :                         result_str = zend_string_alloc(result_len, 0);
    1654     1208518 :                         memcpy(ZSTR_VAL(result_str), Z_STRVAL_P(op1), op1_len);
    1655             :                 }
    1656             : 
    1657             :                 /* This has to happen first to account for the cases where result == op1 == op2 and
    1658             :                  * the realloc is done. In this case this line will also update Z_STRVAL_P(op2) to
    1659             :                  * point to the new string. The first op2_len bytes of result will still be the same. */
    1660     8273071 :                 ZVAL_NEW_STR(result, result_str);
    1661             : 
    1662     8273071 :                 memcpy(ZSTR_VAL(result_str) + op1_len, Z_STRVAL_P(op2), op2_len);
    1663     8273071 :                 ZSTR_VAL(result_str)[result_len] = '\0';
    1664             :         }
    1665             : 
    1666     8273071 :         if (UNEXPECTED(use_copy1)) {
    1667             :                 zval_dtor(op1);
    1668             :         }
    1669     8273071 :         if (UNEXPECTED(use_copy2)) {
    1670             :                 zval_dtor(op2);
    1671             :         }
    1672     8273071 :         return SUCCESS;
    1673             : }
    1674             : /* }}} */
    1675             : 
    1676           0 : ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, zend_bool case_insensitive) /* {{{ */
    1677             : {
    1678           0 :         zend_string *str1 = zval_get_string(op1);
    1679           0 :         zend_string *str2 = zval_get_string(op2);
    1680             :         int ret;
    1681             : 
    1682           0 :         if (case_insensitive) {
    1683           0 :                 ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1));
    1684             :         } else {
    1685           0 :                 ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2));
    1686             :         }
    1687             : 
    1688             :         zend_string_release(str1);
    1689             :         zend_string_release(str2);
    1690           0 :         return ret;
    1691             : }
    1692             : /* }}} */
    1693             : 
    1694      240470 : ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{ */
    1695             : {
    1696      474837 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1697      234367 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1698      232160 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1699         228 :                         return 0;
    1700             :                 } else {
    1701      231932 :                         return zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1702             :                 }
    1703             :         } else {
    1704        8310 :                 zend_string *str1 = zval_get_string(op1);
    1705        8310 :                 zend_string *str2 = zval_get_string(op2);
    1706        8310 :                 int ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2));
    1707             : 
    1708             :                 zend_string_release(str1);
    1709             :                 zend_string_release(str2);
    1710        8310 :                 return ret;
    1711             :         }
    1712             : }
    1713             : /* }}} */
    1714             : 
    1715          99 : ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* {{{ */
    1716             : {
    1717         185 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1718          86 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1719          86 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1720           0 :                         return 0;
    1721             :                 } else {
    1722          86 :                         return zend_binary_strcasecmp_l(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1723             :                 }
    1724             :         } else {
    1725          13 :                 zend_string *str1 = zval_get_string(op1);
    1726          13 :                 zend_string *str2 = zval_get_string(op2);
    1727          13 :                 int ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1));
    1728             : 
    1729             :                 zend_string_release(str1);
    1730             :                 zend_string_release(str2);
    1731          13 :                 return ret;
    1732             :         }
    1733             : }
    1734             : /* }}} */
    1735             : 
    1736             : #if HAVE_STRCOLL
    1737          29 : ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2) /* {{{ */
    1738             : {
    1739          29 :         zend_string *str1 = zval_get_string(op1);
    1740          29 :         zend_string *str2 = zval_get_string(op2);
    1741          29 :         int ret = strcoll(ZSTR_VAL(str1), ZSTR_VAL(str2));
    1742             : 
    1743             :         zend_string_release(str1);
    1744             :         zend_string_release(str2);
    1745          29 :         return ret;
    1746             : }
    1747             : /* }}} */
    1748             : #endif
    1749             : 
    1750         565 : ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2) /* {{{ */
    1751             : {
    1752             :         double d1, d2;
    1753             : 
    1754         565 :         d1 = zval_get_double(op1);
    1755         565 :         d2 = zval_get_double(op2);
    1756             : 
    1757         565 :         return ZEND_NORMALIZE_BOOL(d1 - d2);
    1758             : }
    1759             : /* }}} */
    1760             : 
    1761         415 : static inline void zend_free_obj_get_result(zval *op) /* {{{ */
    1762             : {
    1763         415 :         if (Z_REFCOUNTED_P(op)) {
    1764           1 :                 if (Z_REFCOUNT_P(op) == 0) {
    1765             :                         zval_dtor(op);
    1766             :                 } else {
    1767           1 :                         zval_ptr_dtor(op);
    1768             :                 }
    1769             :         }
    1770         415 : }
    1771             : /* }}} */
    1772             : 
    1773           0 : static void ZEND_FASTCALL convert_compare_result_to_long(zval *result) /* {{{ */
    1774             : {
    1775           0 :         if (Z_TYPE_P(result) == IS_DOUBLE) {
    1776           0 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1777             :         } else {
    1778           0 :                 convert_to_long(result);
    1779             :         }
    1780           0 : }
    1781             : /* }}} */
    1782             : 
    1783      839478 : ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1784             : {
    1785             :         int ret;
    1786      839478 :         int converted = 0;
    1787             :         zval op1_copy, op2_copy;
    1788             :         zval *op_free, tmp_free;
    1789             : 
    1790             :         while (1) {
    1791     2042672 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1792             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1793       65969 :                                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1794       65969 :                                 return SUCCESS;
    1795             : 
    1796             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1797         419 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
    1798         419 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1799         419 :                                 return SUCCESS;
    1800             : 
    1801             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1802         342 :                                 Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
    1803         342 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1804         342 :                                 return SUCCESS;
    1805             : 
    1806             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1807         371 :                                 if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
    1808          95 :                                         ZVAL_LONG(result, 0);
    1809             :                                 } else {
    1810         276 :                                         Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    1811         276 :                                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1812             :                                 }
    1813         371 :                                 return SUCCESS;
    1814             : 
    1815             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
    1816         545 :                                 ZVAL_LONG(result, zend_compare_arrays(op1, op2));
    1817         545 :                                 return SUCCESS;
    1818             : 
    1819             :                         case TYPE_PAIR(IS_NULL, IS_NULL):
    1820             :                         case TYPE_PAIR(IS_NULL, IS_FALSE):
    1821             :                         case TYPE_PAIR(IS_FALSE, IS_NULL):
    1822             :                         case TYPE_PAIR(IS_FALSE, IS_FALSE):
    1823             :                         case TYPE_PAIR(IS_TRUE, IS_TRUE):
    1824        3218 :                                 ZVAL_LONG(result, 0);
    1825        3218 :                                 return SUCCESS;
    1826             : 
    1827             :                         case TYPE_PAIR(IS_NULL, IS_TRUE):
    1828          13 :                                 ZVAL_LONG(result, -1);
    1829          13 :                                 return SUCCESS;
    1830             : 
    1831             :                         case TYPE_PAIR(IS_TRUE, IS_NULL):
    1832          12 :                                 ZVAL_LONG(result, 1);
    1833          12 :                                 return SUCCESS;
    1834             : 
    1835             :                         case TYPE_PAIR(IS_STRING, IS_STRING):
    1836      354326 :                                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1837         227 :                                         ZVAL_LONG(result, 0);
    1838         227 :                                         return SUCCESS;
    1839             :                                 }
    1840      354099 :                                 ZVAL_LONG(result, zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)));
    1841      354099 :                                 return SUCCESS;
    1842             : 
    1843             :                         case TYPE_PAIR(IS_NULL, IS_STRING):
    1844       13191 :                                 ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
    1845       13191 :                                 return SUCCESS;
    1846             : 
    1847             :                         case TYPE_PAIR(IS_STRING, IS_NULL):
    1848         115 :                                 ZVAL_LONG(result, Z_STRLEN_P(op1) == 0 ? 0 : 1);
    1849         115 :                                 return SUCCESS;
    1850             : 
    1851             :                         case TYPE_PAIR(IS_OBJECT, IS_NULL):
    1852          49 :                                 ZVAL_LONG(result, 1);
    1853          49 :                                 return SUCCESS;
    1854             : 
    1855             :                         case TYPE_PAIR(IS_NULL, IS_OBJECT):
    1856          15 :                                 ZVAL_LONG(result, -1);
    1857          15 :                                 return SUCCESS;
    1858             : 
    1859             :                         default:
    1860      582751 :                                 if (Z_ISREF_P(op1)) {
    1861      125010 :                                         op1 = Z_REFVAL_P(op1);
    1862      125010 :                                         continue;
    1863      457741 :                                 } else if (Z_ISREF_P(op2)) {
    1864       27699 :                                         op2 = Z_REFVAL_P(op2);
    1865       27699 :                                         continue;
    1866             :                                 }
    1867             : 
    1868      430042 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
    1869       25018 :                                         ret = Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2);
    1870       25018 :                                         if (UNEXPECTED(Z_TYPE_P(result) != IS_LONG)) {
    1871           0 :                                                 convert_compare_result_to_long(result);
    1872             :                                         }
    1873       25018 :                                         return ret;
    1874      405024 :                                 } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
    1875       25004 :                                         ret = Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2);
    1876       25004 :                                         if (UNEXPECTED(Z_TYPE_P(result) != IS_LONG)) {
    1877           0 :                                                 convert_compare_result_to_long(result);
    1878             :                                         }
    1879       25004 :                                         return ret;
    1880             :                                 }
    1881             : 
    1882      726457 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
    1883      346222 :                                         if (Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
    1884             :                                                 /* object handles are identical, apparently this is the same object */
    1885          25 :                                                 ZVAL_LONG(result, 0);
    1886          25 :                                                 return SUCCESS;
    1887             :                                         }
    1888      346197 :                                         if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
    1889      346196 :                                                 ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2));
    1890      346192 :                                                 return SUCCESS;
    1891             :                                         }
    1892             :                                 }
    1893       33799 :                                 if (Z_TYPE_P(op1) == IS_OBJECT) {
    1894         216 :                                         if (Z_OBJ_HT_P(op1)->get) {
    1895             :                                                 zval rv;
    1896           1 :                                                 op_free = Z_OBJ_HT_P(op1)->get(op1, &rv);
    1897           1 :                                                 ret = compare_function(result, op_free, op2);
    1898           1 :                                                 zend_free_obj_get_result(op_free);
    1899           1 :                                                 return ret;
    1900         215 :                                         } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
    1901         214 :                                                 ZVAL_UNDEF(&tmp_free);
    1902         799 :                                                 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))) == FAILURE) {
    1903         111 :                                                         ZVAL_LONG(result, 1);
    1904         111 :                                                         zend_free_obj_get_result(&tmp_free);
    1905         111 :                                                         return SUCCESS;
    1906             :                                                 }
    1907         103 :                                                 ret = compare_function(result, &tmp_free, op2);
    1908         103 :                                                 zend_free_obj_get_result(&tmp_free);
    1909         103 :                                                 return ret;
    1910             :                                         }
    1911             :                                 }
    1912       33584 :                                 if (Z_TYPE_P(op2) == IS_OBJECT) {
    1913         201 :                                         if (Z_OBJ_HT_P(op2)->get) {
    1914             :                                                 zval rv;
    1915           0 :                                                 op_free = Z_OBJ_HT_P(op2)->get(op2, &rv);
    1916           0 :                                                 ret = compare_function(result, op1, op_free);
    1917           0 :                                                 zend_free_obj_get_result(op_free);
    1918           0 :                                                 return ret;
    1919         201 :                                         } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
    1920         200 :                                                 ZVAL_UNDEF(&tmp_free);
    1921         754 :                                                 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))) == FAILURE) {
    1922         107 :                                                         ZVAL_LONG(result, -1);
    1923         107 :                                                         zend_free_obj_get_result(&tmp_free);
    1924         107 :                                                         return SUCCESS;
    1925             :                                                 }
    1926          93 :                                                 ret = compare_function(result, op1, &tmp_free);
    1927          93 :                                                 zend_free_obj_get_result(&tmp_free);
    1928          93 :                                                 return ret;
    1929           1 :                                         } else if (Z_TYPE_P(op1) == IS_OBJECT) {
    1930           1 :                                                 ZVAL_LONG(result, 1);
    1931           1 :                                                 return SUCCESS;
    1932             :                                         }
    1933             :                                 }
    1934       33383 :                                 if (!converted) {
    1935       65497 :                                         if (Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op1) == IS_FALSE) {
    1936        2149 :                                                 ZVAL_LONG(result, zval_is_true(op2) ? -1 : 0);
    1937        2149 :                                                 return SUCCESS;
    1938       61300 :                                         } else if (Z_TYPE_P(op2) == IS_NULL || Z_TYPE_P(op2) == IS_FALSE) {
    1939        1179 :                                                 ZVAL_LONG(result, zval_is_true(op1) ? 1 : 0);
    1940        1179 :                                                 return SUCCESS;
    1941       29515 :                                         } else if (Z_TYPE_P(op1) == IS_TRUE) {
    1942         184 :                                                 ZVAL_LONG(result, zval_is_true(op2) ? 0 : 1);
    1943         184 :                                                 return SUCCESS;
    1944       29331 :                                         } else if (Z_TYPE_P(op2) == IS_TRUE) {
    1945         182 :                                                 ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
    1946         182 :                                                 return SUCCESS;
    1947             :                                         } else {
    1948       73163 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result, 1);
    1949       72302 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result, 1);
    1950       29149 :                                                 converted = 1;
    1951             :                                         }
    1952         540 :                                 } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    1953         281 :                                         ZVAL_LONG(result, 1);
    1954         281 :                                         return SUCCESS;
    1955         259 :                                 } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    1956         259 :                                         ZVAL_LONG(result, -1);
    1957         259 :                                         return SUCCESS;
    1958           0 :                                 } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    1959           0 :                                         ZVAL_LONG(result, 1);
    1960           0 :                                         return SUCCESS;
    1961           0 :                                 } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    1962           0 :                                         ZVAL_LONG(result, -1);
    1963           0 :                                         return SUCCESS;
    1964             :                                 } else {
    1965           0 :                                         ZVAL_LONG(result, 0);
    1966           0 :                                         return FAILURE;
    1967             :                                 }
    1968             :                 }
    1969      181858 :         }
    1970             : }
    1971             : /* }}} */
    1972             : 
    1973        1144 : static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */
    1974             : {
    1975             :         zval result;
    1976             : 
    1977             :         /* is_identical_function() returns 1 in case of identity and 0 in case
    1978             :          * of a difference;
    1979             :          * whereas this comparison function is expected to return 0 on identity,
    1980             :          * and non zero otherwise.
    1981             :          */
    1982        1144 :         ZVAL_DEREF(z1);
    1983        1144 :         ZVAL_DEREF(z2);
    1984        1144 :         if (is_identical_function(&result, z1, z2)==FAILURE) {
    1985           0 :                 return 1;
    1986             :         }
    1987        1144 :         return Z_TYPE(result) != IS_TRUE;
    1988             : }
    1989             : /* }}} */
    1990             : 
    1991     1073582 : ZEND_API int ZEND_FASTCALL zend_is_identical(zval *op1, zval *op2) /* {{{ */
    1992             : {
    1993     1073582 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    1994           0 :                 return 0;
    1995             :         }
    1996     1073582 :         switch (Z_TYPE_P(op1)) {
    1997             :                 case IS_NULL:
    1998             :                 case IS_FALSE:
    1999             :                 case IS_TRUE:
    2000           3 :                         return 1;
    2001             :                 case IS_LONG:
    2002      963860 :                         return (Z_LVAL_P(op1) == Z_LVAL_P(op2));
    2003             :                 case IS_RESOURCE:
    2004          12 :                         return (Z_RES_P(op1) == Z_RES_P(op2));
    2005             :                 case IS_DOUBLE:
    2006         180 :                         return (Z_DVAL_P(op1) == Z_DVAL_P(op2));
    2007             :                 case IS_STRING:
    2008       79832 :                         return (Z_STR_P(op1) == Z_STR_P(op2) ||
    2009       20127 :                                 (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) &&
    2010       16338 :                                  memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0));
    2011             :                 case IS_ARRAY:
    2012         141 :                         return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
    2013          69 :                                 zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0);
    2014             :                 case IS_OBJECT:
    2015       66088 :                         return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2));
    2016             :                 default:
    2017           0 :                         return 0;
    2018             :         }
    2019             : }
    2020             : /* }}} */
    2021             : 
    2022        1149 : ZEND_API int ZEND_FASTCALL is_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2023             : {
    2024        1149 :         ZVAL_BOOL(result, zend_is_identical(op1, op2));
    2025        1149 :         return SUCCESS;
    2026             : }
    2027             : /* }}} */
    2028             : 
    2029          20 : ZEND_API int ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2030             : {
    2031          20 :         ZVAL_BOOL(result, !zend_is_identical(op1, op2));
    2032          20 :         return SUCCESS;
    2033             : }
    2034             : /* }}} */
    2035             : 
    2036          82 : ZEND_API int ZEND_FASTCALL is_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2037             : {
    2038          82 :         if (compare_function(result, op1, op2) == FAILURE) {
    2039           0 :                 return FAILURE;
    2040             :         }
    2041          82 :         ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
    2042          82 :         return SUCCESS;
    2043             : }
    2044             : /* }}} */
    2045             : 
    2046         419 : ZEND_API int ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2047             : {
    2048         419 :         if (compare_function(result, op1, op2) == FAILURE) {
    2049           0 :                 return FAILURE;
    2050             :         }
    2051         419 :         ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
    2052         419 :         return SUCCESS;
    2053             : }
    2054             : /* }}} */
    2055             : 
    2056        1956 : ZEND_API int ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2057             : {
    2058        1956 :         if (compare_function(result, op1, op2) == FAILURE) {
    2059           0 :                 return FAILURE;
    2060             :         }
    2061        1956 :         ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
    2062        1956 :         return SUCCESS;
    2063             : }
    2064             : /* }}} */
    2065             : 
    2066        1290 : ZEND_API int ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2067             : {
    2068        1290 :         if (compare_function(result, op1, op2) == FAILURE) {
    2069           0 :                 return FAILURE;
    2070             :         }
    2071        1290 :         ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
    2072        1290 :         return SUCCESS;
    2073             : }
    2074             : /* }}} */
    2075             : 
    2076           0 : static zend_bool ZEND_FASTCALL instanceof_interface_only(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2077             : {
    2078             :         uint32_t i;
    2079             : 
    2080           0 :         for (i = 0; i < instance_ce->num_interfaces; i++) {
    2081           0 :                 if (instanceof_interface_only(instance_ce->interfaces[i], ce)) {
    2082           0 :                         return 1;
    2083             :                 }
    2084             :         }
    2085           0 :         return 0;
    2086             : }
    2087             : /* }}} */
    2088             : 
    2089             : static zend_always_inline zend_bool instanceof_class(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2090             : {
    2091     4615763 :         while (instance_ce) {
    2092     3970623 :                 if (instance_ce == ce) {
    2093     2016666 :                         return 1;
    2094             :                 }
    2095     1953957 :                 instance_ce = instance_ce->parent;
    2096             :         }
    2097      645140 :         return 0;
    2098             : }
    2099             : /* }}} */
    2100             : 
    2101     1326143 : static zend_bool ZEND_FASTCALL instanceof_interface(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2102             : {
    2103             :         uint32_t i;
    2104             : 
    2105     1784714 :         for (i = 0; i < instance_ce->num_interfaces; i++) {
    2106      892501 :                 if (instanceof_interface(instance_ce->interfaces[i], ce)) {
    2107      433930 :                         return 1;
    2108             :                 }
    2109             :         }
    2110      892213 :         return instanceof_class(instance_ce, ce);
    2111             : }
    2112             : /* }}} */
    2113             : 
    2114       74845 : ZEND_API zend_bool ZEND_FASTCALL instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only) /* {{{ */
    2115             : {
    2116       74845 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    2117       74838 :                 if (!interfaces_only) {
    2118           0 :                         if (instanceof_interface_only(instance_ce, ce)) {
    2119           0 :                                 return 1;
    2120             :                         }
    2121             :                 } else {
    2122       74838 :                         return instanceof_interface(instance_ce, ce);
    2123             :                 }
    2124             :         }
    2125           7 :         if (!interfaces_only) {
    2126           7 :                 return instanceof_class(instance_ce, ce);
    2127             :         }
    2128           0 :         return 0;
    2129             : }
    2130             : /* }}} */
    2131             : 
    2132     2128390 : ZEND_API zend_bool ZEND_FASTCALL instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2133             : {
    2134     2128390 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    2135      358804 :                 return instanceof_interface(instance_ce, ce);
    2136             :         } else {
    2137     1769586 :                 return instanceof_class(instance_ce, ce);
    2138             :         }
    2139             : }
    2140             : /* }}} */
    2141             : 
    2142             : #define LOWER_CASE 1
    2143             : #define UPPER_CASE 2
    2144             : #define NUMERIC 3
    2145             : 
    2146      100063 : static void ZEND_FASTCALL increment_string(zval *str) /* {{{ */
    2147             : {
    2148      100063 :         int carry=0;
    2149      100063 :         size_t pos=Z_STRLEN_P(str)-1;
    2150             :         char *s;
    2151             :         zend_string *t;
    2152      100063 :         int last=0; /* Shut up the compiler warning */
    2153             :         int ch;
    2154             : 
    2155      100063 :         if (Z_STRLEN_P(str) == 0) {
    2156           0 :                 zend_string_release(Z_STR_P(str));
    2157           0 :                 if (CG(one_char_string)['1']) {
    2158           0 :                         ZVAL_INTERNED_STR(str, CG(one_char_string)['1']);
    2159             :                 } else {
    2160           0 :                         Z_STR_P(str) = zend_string_init("1", sizeof("1")-1, 0);
    2161           0 :                         Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2162             :                 }
    2163           0 :                 return;
    2164             :         }
    2165             : 
    2166      100063 :         if (!Z_REFCOUNTED_P(str)) {
    2167          16 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2168           8 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2169      100055 :         } else if (Z_REFCOUNT_P(str) > 1) {
    2170             :                 Z_DELREF_P(str);
    2171           0 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2172             :         } else {
    2173      100055 :                 zend_string_forget_hash_val(Z_STR_P(str));
    2174             :         }
    2175      100063 :         s = Z_STRVAL_P(str);
    2176             : 
    2177             :         do {
    2178      104071 :                 ch = s[pos];
    2179      208113 :                 if (ch >= 'a' && ch <= 'z') {
    2180      104042 :                         if (ch == 'z') {
    2181        4007 :                                 s[pos] = 'a';
    2182        4007 :                                 carry=1;
    2183             :                         } else {
    2184      100035 :                                 s[pos]++;
    2185      100035 :                                 carry=0;
    2186             :                         }
    2187      104042 :                         last=LOWER_CASE;
    2188          40 :                 } else if (ch >= 'A' && ch <= 'Z') {
    2189          11 :                         if (ch == 'Z') {
    2190           4 :                                 s[pos] = 'A';
    2191           4 :                                 carry=1;
    2192             :                         } else {
    2193           7 :                                 s[pos]++;
    2194           7 :                                 carry=0;
    2195             :                         }
    2196          11 :                         last=UPPER_CASE;
    2197          32 :                 } else if (ch >= '0' && ch <= '9') {
    2198          14 :                         if (ch == '9') {
    2199           6 :                                 s[pos] = '0';
    2200           6 :                                 carry=1;
    2201             :                         } else {
    2202           8 :                                 s[pos]++;
    2203           8 :                                 carry=0;
    2204             :                         }
    2205          14 :                         last = NUMERIC;
    2206             :                 } else {
    2207           4 :                         carry=0;
    2208           4 :                         break;
    2209             :                 }
    2210      104067 :                 if (carry == 0) {
    2211      100050 :                         break;
    2212             :                 }
    2213        4017 :         } while (pos-- > 0);
    2214             : 
    2215      100063 :         if (carry) {
    2216          18 :                 t = zend_string_alloc(Z_STRLEN_P(str)+1, 0);
    2217           9 :                 memcpy(ZSTR_VAL(t) + 1, Z_STRVAL_P(str), Z_STRLEN_P(str));
    2218           9 :                 ZSTR_VAL(t)[Z_STRLEN_P(str) + 1] = '\0';
    2219           9 :                 switch (last) {
    2220             :                         case NUMERIC:
    2221           2 :                                 ZSTR_VAL(t)[0] = '1';
    2222           2 :                                 break;
    2223             :                         case UPPER_CASE:
    2224           2 :                                 ZSTR_VAL(t)[0] = 'A';
    2225           2 :                                 break;
    2226             :                         case LOWER_CASE:
    2227           5 :                                 ZSTR_VAL(t)[0] = 'a';
    2228             :                                 break;
    2229             :                 }
    2230           9 :                 zend_string_free(Z_STR_P(str));
    2231           9 :                 ZVAL_NEW_STR(str, t);
    2232             :         }
    2233             : }
    2234             : /* }}} */
    2235             : 
    2236      118869 : ZEND_API int ZEND_FASTCALL increment_function(zval *op1) /* {{{ */
    2237             : {
    2238             : try_again:
    2239      118869 :         switch (Z_TYPE_P(op1)) {
    2240             :                 case IS_LONG:
    2241             :                         fast_long_increment_function(op1);
    2242       17152 :                         break;
    2243             :                 case IS_DOUBLE:
    2244           4 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
    2245           4 :                         break;
    2246             :                 case IS_NULL:
    2247          30 :                         ZVAL_LONG(op1, 1);
    2248          30 :                         break;
    2249             :                 case IS_STRING: {
    2250             :                                 zend_long lval;
    2251             :                                 double dval;
    2252             : 
    2253      203360 :                                 switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2254             :                                         case IS_LONG:
    2255        1611 :                                                 zend_string_release(Z_STR_P(op1));
    2256        1611 :                                                 if (lval == ZEND_LONG_MAX) {
    2257             :                                                         /* switch to double */
    2258           0 :                                                         double d = (double)lval;
    2259           0 :                                                         ZVAL_DOUBLE(op1, d+1);
    2260             :                                                 } else {
    2261        1611 :                                                         ZVAL_LONG(op1, lval+1);
    2262             :                                                 }
    2263        1611 :                                                 break;
    2264             :                                         case IS_DOUBLE:
    2265           6 :                                                 zend_string_release(Z_STR_P(op1));
    2266           6 :                                                 ZVAL_DOUBLE(op1, dval+1);
    2267           6 :                                                 break;
    2268             :                                         default:
    2269             :                                                 /* Perl style string increment */
    2270      100063 :                                                 increment_string(op1);
    2271             :                                                 break;
    2272             :                                 }
    2273             :                         }
    2274      101680 :                         break;
    2275             :                 case IS_OBJECT:
    2276           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2277           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2278             :                                 /* proxy object */
    2279             :                                 zval rv;
    2280             :                                 zval *val;
    2281             : 
    2282           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
    2283           0 :                                 Z_TRY_ADDREF_P(val);
    2284           0 :                                 increment_function(val);
    2285           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val);
    2286           0 :                                 zval_ptr_dtor(val);
    2287           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2288             :                                 zval op2;
    2289             :                                 int res;
    2290             : 
    2291           2 :                                 ZVAL_LONG(&op2, 1);
    2292           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, &op2);
    2293           2 :                                 zval_ptr_dtor(&op2);
    2294             : 
    2295           2 :                                 return res;
    2296             :                         }
    2297           1 :                         return FAILURE;
    2298             :                 case IS_REFERENCE:
    2299           0 :                         op1 = Z_REFVAL_P(op1);
    2300           0 :                         goto try_again;
    2301             :                 default:
    2302           0 :                         return FAILURE;
    2303             :         }
    2304      118866 :         return SUCCESS;
    2305             : }
    2306             : /* }}} */
    2307             : 
    2308      174919 : ZEND_API int ZEND_FASTCALL decrement_function(zval *op1) /* {{{ */
    2309             : {
    2310             :         zend_long lval;
    2311             :         double dval;
    2312             : 
    2313             : try_again:
    2314      174919 :         switch (Z_TYPE_P(op1)) {
    2315             :                 case IS_LONG:
    2316             :                         fast_long_decrement_function(op1);
    2317          29 :                         break;
    2318             :                 case IS_DOUBLE:
    2319      174849 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
    2320      174849 :                         break;
    2321             :                 case IS_STRING:         /* Like perl we only support string increment */
    2322          33 :                         if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
    2323           1 :                                 zend_string_release(Z_STR_P(op1));
    2324           1 :                                 ZVAL_LONG(op1, -1);
    2325           1 :                                 break;
    2326             :                         }
    2327          64 :                         switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2328             :                                 case IS_LONG:
    2329           8 :                                         zend_string_release(Z_STR_P(op1));
    2330           8 :                                         if (lval == ZEND_LONG_MIN) {
    2331           1 :                                                 double d = (double)lval;
    2332           1 :                                                 ZVAL_DOUBLE(op1, d-1);
    2333             :                                         } else {
    2334           7 :                                                 ZVAL_LONG(op1, lval-1);
    2335             :                                         }
    2336           8 :                                         break;
    2337             :                                 case IS_DOUBLE:
    2338           7 :                                         zend_string_release(Z_STR_P(op1));
    2339           7 :                                         ZVAL_DOUBLE(op1, dval - 1);
    2340             :                                         break;
    2341             :                         }
    2342          32 :                         break;
    2343             :                 case IS_OBJECT:
    2344           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2345           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2346             :                                 /* proxy object */
    2347             :                                 zval rv;
    2348             :                                 zval *val;
    2349             : 
    2350           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
    2351           0 :                                 Z_TRY_ADDREF_P(val);
    2352           0 :                                 decrement_function(val);
    2353           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val);
    2354           0 :                                 zval_ptr_dtor(val);
    2355           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2356             :                                 zval op2;
    2357             :                                 int res;
    2358             : 
    2359           2 :                                 ZVAL_LONG(&op2, 1);
    2360           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, &op2);
    2361           2 :                                 zval_ptr_dtor(&op2);
    2362             : 
    2363           2 :                                 return res;
    2364             :                         }
    2365           1 :                         return FAILURE;
    2366             :                 case IS_REFERENCE:
    2367           0 :                         op1 = Z_REFVAL_P(op1);
    2368           0 :                         goto try_again;
    2369             :                 default:
    2370           5 :                         return FAILURE;
    2371             :         }
    2372             : 
    2373      174911 :         return SUCCESS;
    2374             : }
    2375             : /* }}} */
    2376             : 
    2377      119762 : ZEND_API int ZEND_FASTCALL zend_is_true(zval *op) /* {{{ */
    2378             : {
    2379      119761 :         return i_zend_is_true(op);
    2380             : }
    2381             : /* }}} */
    2382             : 
    2383      162686 : ZEND_API int ZEND_FASTCALL zend_object_is_true(zval *op) /* {{{ */
    2384             : {
    2385      162686 :         if (Z_OBJ_HT_P(op)->cast_object) {
    2386             :                 zval tmp;
    2387      162686 :                 if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL) == SUCCESS) {
    2388      162685 :                         return Z_TYPE(tmp) == IS_TRUE;
    2389             :                 }
    2390           1 :                 zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", ZSTR_VAL(Z_OBJ_P(op)->ce->name));
    2391           0 :         } else if (Z_OBJ_HT_P(op)->get) {
    2392             :                 int result;
    2393             :                 zval rv;
    2394           0 :                 zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv);
    2395             : 
    2396           0 :                 if (Z_TYPE_P(tmp) != IS_OBJECT) {
    2397             :                         /* for safety - avoid loop */
    2398           0 :                         result = i_zend_is_true(tmp);
    2399           0 :                         zval_ptr_dtor(tmp);
    2400           0 :                         return result;
    2401             :                 }
    2402             :         }
    2403           0 :         return 1;
    2404             : }
    2405             : /* }}} */
    2406             : 
    2407             : #ifdef ZEND_USE_TOLOWER_L
    2408             : ZEND_API void zend_update_current_locale(void) /* {{{ */
    2409             : {
    2410             :         current_locale = _get_current_locale();
    2411             : }
    2412             : /* }}} */
    2413             : #endif
    2414             : 
    2415   167615852 : ZEND_API char* ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length) /* {{{ */
    2416             : {
    2417   167615852 :         register unsigned char *str = (unsigned char*)source;
    2418   167615852 :         register unsigned char *result = (unsigned char*)dest;
    2419   167615852 :         register unsigned char *end = str + length;
    2420             : 
    2421  2573677482 :         while (str < end) {
    2422  2238445778 :                 *result++ = zend_tolower_ascii(*str++);
    2423             :         }
    2424   167615852 :         *result = '\0';
    2425             : 
    2426   167615852 :         return dest;
    2427             : }
    2428             : /* }}} */
    2429             : 
    2430     5221960 : ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t length) /* {{{ */
    2431             : {
    2432     5221960 :         return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
    2433             : }
    2434             : /* }}} */
    2435             : 
    2436       91654 : ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length) /* {{{ */
    2437             : {
    2438       91654 :         register unsigned char *p = (unsigned char*)str;
    2439       91654 :         register unsigned char *end = p + length;
    2440             : 
    2441      820269 :         while (p < end) {
    2442      636961 :                 *p = zend_tolower_ascii(*p);
    2443      636961 :                 p++;
    2444             :         }
    2445       91654 : }
    2446             : /* }}} */
    2447             : 
    2448         286 : ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup_ex(const char *source, size_t length) /* {{{ */
    2449             : {
    2450         286 :         register const unsigned char *p = (const unsigned char*)source;
    2451         286 :         register const unsigned char *end = p + length;
    2452             : 
    2453        4712 :         while (p < end) {
    2454        4150 :                 if (*p != zend_tolower_ascii(*p)) {
    2455          10 :                         char *res = (char*)emalloc(length + 1);
    2456             :                         register unsigned char *r;
    2457             : 
    2458          10 :                         if (p != (const unsigned char*)source) {
    2459           2 :                                 memcpy(res, source, p - (const unsigned char*)source);
    2460             :                         }
    2461          10 :                         r = (unsigned char*)p + (res - source);
    2462          93 :                         while (p < end) {
    2463          73 :                                 *r = zend_tolower_ascii(*p);
    2464          73 :                                 p++;
    2465          73 :                                 r++;
    2466             :                         }
    2467          10 :                         *r = '\0';
    2468          10 :                         return res;
    2469             :                 }
    2470        4140 :                 p++;
    2471             :         }
    2472         276 :         return NULL;
    2473             : }
    2474             : /* }}} */
    2475             : 
    2476      627279 : ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower(zend_string *str) /* {{{ */
    2477             : {
    2478      627279 :         register unsigned char *p = (unsigned char*)ZSTR_VAL(str);
    2479      627279 :         register unsigned char *end = p + ZSTR_LEN(str);
    2480             : 
    2481    36859654 :         while (p < end) {
    2482    35816643 :                 if (*p != zend_tolower_ascii(*p)) {
    2483      423094 :                         zend_string *res = zend_string_alloc(ZSTR_LEN(str), 0);
    2484             :                         register unsigned char *r;
    2485             : 
    2486      211547 :                         if (p != (unsigned char*)ZSTR_VAL(str)) {
    2487       46986 :                                 memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char*)ZSTR_VAL(str));
    2488             :                         }
    2489      211547 :                         r = p + (ZSTR_VAL(res) - ZSTR_VAL(str));
    2490     1185669 :                         while (p < end) {
    2491      762575 :                                 *r = zend_tolower_ascii(*p);
    2492      762575 :                                 p++;
    2493      762575 :                                 r++;
    2494             :                         }
    2495      211547 :                         *r = '\0';
    2496      211547 :                         return res;
    2497             :                 }
    2498    35605096 :                 p++;
    2499             :         }
    2500      415732 :         return zend_string_copy(str);
    2501             : }
    2502             : /* }}} */
    2503             : 
    2504      922017 : ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2505             : {
    2506             :         int retval;
    2507             : 
    2508      922017 :         if (s1 == s2) {
    2509         321 :                 return 0;
    2510             :         }
    2511      921696 :         retval = memcmp(s1, s2, MIN(len1, len2));
    2512      921696 :         if (!retval) {
    2513      232321 :                 return (int)(len1 - len2);
    2514             :         } else {
    2515      689375 :                 return retval;
    2516             :         }
    2517             : }
    2518             : /* }}} */
    2519             : 
    2520       16557 : ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2521             : {
    2522             :         int retval;
    2523             : 
    2524       16557 :         if (s1 == s2) {
    2525          44 :                 return 0;
    2526             :         }
    2527       16513 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    2528       16513 :         if (!retval) {
    2529       16235 :                 return (int)(MIN(length, len1) - MIN(length, len2));
    2530             :         } else {
    2531         278 :                 return retval;
    2532             :         }
    2533             : }
    2534             : /* }}} */
    2535             : 
    2536     1081584 : ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2537             : {
    2538             :         size_t len;
    2539             :         int c1, c2;
    2540             : 
    2541     1081584 :         if (s1 == s2) {
    2542          80 :                 return 0;
    2543             :         }
    2544             : 
    2545     1081504 :         len = MIN(len1, len2);
    2546     3685534 :         while (len--) {
    2547     2452694 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2548     2452694 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2549     2452694 :                 if (c1 != c2) {
    2550      930168 :                         return c1 - c2;
    2551             :                 }
    2552             :         }
    2553             : 
    2554      151336 :         return (int)(len1 - len2);
    2555             : }
    2556             : /* }}} */
    2557             : 
    2558       23394 : ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2559             : {
    2560             :         size_t len;
    2561             :         int c1, c2;
    2562             : 
    2563       23394 :         if (s1 == s2) {
    2564          45 :                 return 0;
    2565             :         }
    2566       23349 :         len = MIN(length, MIN(len1, len2));
    2567       55356 :         while (len--) {
    2568        9178 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2569        9178 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2570        9178 :                 if (c1 != c2) {
    2571         520 :                         return c1 - c2;
    2572             :                 }
    2573             :         }
    2574             : 
    2575       22829 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2576             : }
    2577             : /* }}} */
    2578             : 
    2579         123 : ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2580             : {
    2581             :         size_t len;
    2582             :         int c1, c2;
    2583             : 
    2584         123 :         if (s1 == s2) {
    2585           0 :                 return 0;
    2586             :         }
    2587             : 
    2588         123 :         len = MIN(len1, len2);
    2589         560 :         while (len--) {
    2590         400 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2591         400 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2592         400 :                 if (c1 != c2) {
    2593          86 :                         return c1 - c2;
    2594             :                 }
    2595             :         }
    2596             : 
    2597          37 :         return (int)(len1 - len2);
    2598             : }
    2599             : /* }}} */
    2600             : 
    2601           4 : ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2602             : {
    2603             :         size_t len;
    2604             :         int c1, c2;
    2605             : 
    2606           4 :         if (s1 == s2) {
    2607           0 :                 return 0;
    2608             :         }
    2609           4 :         len = MIN(length, MIN(len1, len2));
    2610          19 :         while (len--) {
    2611          12 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2612          12 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2613          12 :                 if (c1 != c2) {
    2614           1 :                         return c1 - c2;
    2615             :                 }
    2616             :         }
    2617             : 
    2618           3 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2619             : }
    2620             : /* }}} */
    2621             : 
    2622           2 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2623             : {
    2624           2 :         return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2625             : }
    2626             : /* }}} */
    2627             : 
    2628           0 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2629             : {
    2630           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));
    2631             : }
    2632             : /* }}} */
    2633             : 
    2634           0 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
    2635             : {
    2636           0 :         return zend_binary_strcasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2637             : }
    2638             : /* }}} */
    2639             : 
    2640           0 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2641             : {
    2642           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));
    2643             : }
    2644             : /* }}} */
    2645             : 
    2646      650848 : ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */
    2647             : {
    2648             :         int ret1, ret2;
    2649             :         int oflow1, oflow2;
    2650      650848 :         zend_long lval1 = 0, lval2 = 0;
    2651      650848 :         double dval1 = 0.0, dval2 = 0.0;
    2652             : 
    2653     1608489 :         if ((ret1 = is_numeric_string_ex(s1->val, s1->len, &lval1, &dval1, 0, &oflow1)) &&
    2654      306793 :                 (ret2 = is_numeric_string_ex(s2->val, s2->len, &lval2, &dval2, 0, &oflow2))) {
    2655             : #if ZEND_ULONG_MAX == 0xFFFFFFFF
    2656             :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
    2657             :                         ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
    2658             :                         || (oflow1 == -1 && dval1 < -9007199254740991.))) {
    2659             : #else
    2660      306645 :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
    2661             : #endif
    2662             :                         /* both values are integers overflown to the same side, and the
    2663             :                          * double comparison may have resulted in crucial accuracy lost */
    2664        1113 :                         goto string_cmp;
    2665             :                 }
    2666      305532 :                 if ((ret1 == IS_DOUBLE) || (ret2 == IS_DOUBLE)) {
    2667      100198 :                         if (ret1 != IS_DOUBLE) {
    2668          34 :                                 if (oflow2) {
    2669             :                                         /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
    2670           2 :                                         return -1 * oflow2;
    2671             :                                 }
    2672          32 :                                 dval1 = (double) lval1;
    2673      100164 :                         } else if (ret2 != IS_DOUBLE) {
    2674          13 :                                 if (oflow1) {
    2675           0 :                                         return oflow1;
    2676             :                                 }
    2677          13 :                                 dval2 = (double) lval2;
    2678      100151 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2679             :                                 /* Both values overflowed and have the same sign,
    2680             :                                  * so a numeric comparison would be inaccurate */
    2681           4 :                                 goto string_cmp;
    2682             :                         }
    2683      100192 :                         dval1 = dval1 - dval2;
    2684      100192 :                         return ZEND_NORMALIZE_BOOL(dval1);
    2685             :                 } else { /* they both have to be long's */
    2686      205334 :                         return lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0);
    2687             :                 }
    2688             :         } else {
    2689             :                 int strcmp_ret;
    2690             : string_cmp:
    2691      345320 :                 strcmp_ret = zend_binary_strcmp(s1->val, s1->len, s2->val, s2->len);
    2692      345320 :                 return ZEND_NORMALIZE_BOOL(strcmp_ret);
    2693             :         }
    2694             : }
    2695             : /* }}} */
    2696             : 
    2697        2926 : static int hash_zval_compare_function(zval *z1, zval *z2) /* {{{ */
    2698             : {
    2699             :         zval result;
    2700             : 
    2701        2926 :         if (compare_function(&result, z1, z2)==FAILURE) {
    2702           0 :                 return 1;
    2703             :         }
    2704        2926 :         return Z_LVAL(result);
    2705             : }
    2706             : /* }}} */
    2707             : 
    2708         866 : ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2) /* {{{ */
    2709             : {
    2710         866 :         return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0);
    2711             : }
    2712             : /* }}} */
    2713             : 
    2714         545 : ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2) /* {{{ */
    2715             : {
    2716         545 :         return zend_compare_symbol_tables(Z_ARRVAL_P(a1), Z_ARRVAL_P(a2));
    2717             : }
    2718             : /* }}} */
    2719             : 
    2720           1 : ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2) /* {{{ */
    2721             : {
    2722           1 :         if (Z_OBJ_P(o1) == Z_OBJ_P(o2)) {
    2723           1 :                 return 0;
    2724             :         }
    2725             : 
    2726           0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2727           0 :                 return 1;
    2728             :         } else {
    2729           0 :                 return Z_OBJ_HT_P(o1)->compare_objects(o1, o2);
    2730             :         }
    2731             : }
    2732             : /* }}} */
    2733             : 
    2734           0 : ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
    2735             : {
    2736             :         zend_string *str;
    2737             : 
    2738           0 :         str = zend_strpprintf(0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
    2739           0 :         ZVAL_NEW_STR(op, str);
    2740           0 : }
    2741             : /* }}} */
    2742             : 
    2743      484975 : ZEND_API zend_string* ZEND_FASTCALL zend_long_to_str(zend_long num) /* {{{ */
    2744             : {
    2745             :         char buf[MAX_LENGTH_OF_LONG + 1];
    2746      484975 :         char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
    2747      969950 :         return zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
    2748             : }
    2749             : /* }}} */
    2750             : 
    2751       32447 : ZEND_API zend_uchar ZEND_FASTCALL is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval) /* {{{ */ {
    2752       64894 :     return is_numeric_string_ex(ZSTR_VAL(str), ZSTR_LEN(str), lval, dval, -1, NULL);
    2753             : }
    2754             : /* }}} */
    2755             : 
    2756      973995 : ZEND_API zend_uchar ZEND_FASTCALL _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info) /* {{{ */
    2757             : {
    2758             :         const char *ptr;
    2759      973995 :         int digits = 0, dp_or_e = 0;
    2760      973995 :         double local_dval = 0.0;
    2761             :         zend_uchar type;
    2762      973995 :         zend_long tmp_lval = 0;
    2763      973995 :         int neg = 0;
    2764             : 
    2765      973995 :         if (!length) {
    2766        1532 :                 return 0;
    2767             :         }
    2768             : 
    2769      972463 :         if (oflow_info != NULL) {
    2770      831238 :                 *oflow_info = 0;
    2771             :         }
    2772             : 
    2773             :         /* Skip any whitespace
    2774             :          * This is much faster than the isspace() function */
    2775     1946879 :         while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
    2776        1953 :                 str++;
    2777        1953 :                 length--;
    2778             :         }
    2779      972463 :         ptr = str;
    2780             : 
    2781      972463 :         if (*ptr == '-') {
    2782        2265 :                 neg = 1;
    2783        2265 :                 ptr++;
    2784      970198 :         } else if (*ptr == '+') {
    2785         743 :                 ptr++;
    2786             :         }
    2787             : 
    2788     1534725 :         if (ZEND_IS_DIGIT(*ptr)) {
    2789             :                 /* Skip any leading 0s */
    2790     1804227 :                 while (*ptr == '0') {
    2791      267585 :                         ptr++;
    2792             :                 }
    2793             : 
    2794             :                 /* Count the number of digits. If a decimal point/exponent is found,
    2795             :                  * it's a double. Otherwise, if there's a dval or no need to check for
    2796             :                  * a full match, stop when there are too many digits for a long */
    2797    10918364 :                 for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
    2798             : check_digits:
    2799     5457004 :                         if (ZEND_IS_DIGIT(*ptr)) {
    2800     4690861 :                                 tmp_lval = tmp_lval * 10 + (*ptr) - '0';
    2801     4690861 :                                 continue;
    2802      766143 :                         } else if (*ptr == '.' && dp_or_e < 1) {
    2803             :                                 goto process_double;
    2804      562760 :                         } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
    2805         536 :                                 const char *e = ptr + 1;
    2806             : 
    2807         536 :                                 if (*e == '-' || *e == '+') {
    2808           9 :                                         ptr = e++;
    2809             :                                 }
    2810         536 :                                 if (ZEND_IS_DIGIT(*e)) {
    2811         491 :                                         goto process_double;
    2812             :                                 }
    2813             :                         }
    2814             : 
    2815      562269 :                         break;
    2816             :                 }
    2817             : 
    2818      564503 :                 if (digits >= MAX_LENGTH_OF_LONG) {
    2819        2241 :                         if (oflow_info != NULL) {
    2820        2229 :                                 *oflow_info = *str == '-' ? -1 : 1;
    2821             :                         }
    2822        2241 :                         dp_or_e = -1;
    2823        2241 :                         goto process_double;
    2824             :                 }
    2825      410361 :         } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
    2826             : process_double:
    2827      206275 :                 type = IS_DOUBLE;
    2828             : 
    2829             :                 /* If there's a dval, do the conversion; else continue checking
    2830             :                  * the digits if we need to check for a full match */
    2831      206275 :                 if (dval) {
    2832      206212 :                         local_dval = zend_strtod(str, &ptr);
    2833          63 :                 } else if (allow_errors != 1 && dp_or_e != -1) {
    2834          56 :                         dp_or_e = (*ptr++ == '.') ? 1 : 2;
    2835          56 :                         goto check_digits;
    2836             :                 }
    2837             :         } else {
    2838      203982 :                 return 0;
    2839             :         }
    2840             : 
    2841      768481 :         if (ptr != str + length) {
    2842       15648 :                 if (!allow_errors) {
    2843       14100 :                         return 0;
    2844             :                 }
    2845        1548 :                 if (allow_errors == -1) {
    2846        1326 :                         zend_error(E_NOTICE, "A non well formed numeric value encountered");
    2847             :                 }
    2848             :         }
    2849             : 
    2850      754381 :         if (type == IS_LONG) {
    2851      548929 :                 if (digits == MAX_LENGTH_OF_LONG - 1) {
    2852         184 :                         int cmp = strcmp(&ptr[-digits], long_min_digits);
    2853             : 
    2854         184 :                         if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
    2855           2 :                                 if (dval) {
    2856           2 :                                         *dval = zend_strtod(str, NULL);
    2857             :                                 }
    2858           2 :                                 if (oflow_info != NULL) {
    2859           2 :                                         *oflow_info = *str == '-' ? -1 : 1;
    2860             :                                 }
    2861             : 
    2862           2 :                                 return IS_DOUBLE;
    2863             :                         }
    2864             :                 }
    2865             : 
    2866      548927 :                 if (lval) {
    2867      548852 :                         if (neg) {
    2868         666 :                                 tmp_lval = -tmp_lval;
    2869             :                         }
    2870      548852 :                         *lval = tmp_lval;
    2871             :                 }
    2872             : 
    2873      548927 :                 return IS_LONG;
    2874             :         } else {
    2875      205452 :                 if (dval) {
    2876      205418 :                         *dval = local_dval;
    2877             :                 }
    2878             : 
    2879      205452 :                 return IS_DOUBLE;
    2880             :         }
    2881             : }
    2882             : /* }}} */
    2883             : 
    2884             : /* 
    2885             :  * String matching - Sunday algorithm
    2886             :  * http://www.iti.fh-flensburg.de/lang/algorithmen/pattern/sundayen.htm
    2887             :  */
    2888             : static zend_always_inline void zend_memnstr_ex_pre(unsigned int td[], const char *needle, size_t needle_len, int reverse) /* {{{ */ {
    2889             :         int i;
    2890             : 
    2891     4095809 :         for (i = 0; i < 256; i++) {
    2892     4079872 :                 td[i] = needle_len + 1;
    2893             :         }
    2894             : 
    2895       15937 :         if (reverse) {
    2896           0 :                 for (i = needle_len - 1; i >= 0; i--) {
    2897           0 :                         td[(unsigned char)needle[i]] = i + 1;
    2898             :                 }
    2899             :         } else {
    2900             :                 size_t i;
    2901             : 
    2902      248282 :                 for (i = 0; i < needle_len; i++) {
    2903      232345 :                         td[(unsigned char)needle[i]] = (int)needle_len - i;
    2904             :                 }
    2905             :         }
    2906             : }
    2907             : /* }}} */
    2908             : 
    2909       15937 : ZEND_API const char* ZEND_FASTCALL zend_memnstr_ex(const char *haystack, const char *needle, size_t needle_len, const char *end) /* {{{ */
    2910             : {
    2911             :         unsigned int td[256];
    2912             :         register size_t i;
    2913             :         register const char *p;
    2914             : 
    2915       15937 :         if (needle_len == 0 || (end - haystack) == 0) {
    2916           0 :                 return NULL;
    2917             :         }
    2918             : 
    2919             :         zend_memnstr_ex_pre(td, needle, needle_len, 0);
    2920             : 
    2921       15937 :         p = haystack;
    2922       15937 :         end -= needle_len;
    2923             : 
    2924     5469569 :         while (p <= end) {
    2925     6596018 :                 for (i = 0; i < needle_len; i++) {
    2926     6591519 :                         if (needle[i] != p[i]) {
    2927     5439088 :                                 break;
    2928             :                         }
    2929             :                 }
    2930     5443587 :                 if (i == needle_len) {
    2931        4499 :                         return p;
    2932             :                 }
    2933     5439088 :                 if (UNEXPECTED(p == end)) {
    2934        1393 :                         return NULL;
    2935             :                 }
    2936     5437695 :                 p += td[(unsigned char)(p[needle_len])];
    2937             :         }
    2938             : 
    2939       10045 :         return NULL;
    2940             : }
    2941             : /* }}} */
    2942             : 
    2943           0 : ZEND_API const char* ZEND_FASTCALL zend_memnrstr_ex(const char *haystack, const char *needle, size_t needle_len, const char *end) /* {{{ */
    2944             : {
    2945             :         unsigned int td[256];
    2946             :         register size_t i;
    2947             :         register const char *p;
    2948             : 
    2949           0 :         if (needle_len == 0 || (end - haystack) == 0) {
    2950           0 :                 return NULL;
    2951             :         }
    2952             : 
    2953             :         zend_memnstr_ex_pre(td, needle, needle_len, 1);
    2954             : 
    2955           0 :         p = end;
    2956           0 :         p -= needle_len;
    2957             : 
    2958           0 :         while (p >= haystack) {
    2959           0 :                 for (i = 0; i < needle_len; i++) {
    2960           0 :                         if (needle[i] != p[i]) {
    2961           0 :                                 break;
    2962             :                         }
    2963             :                 }
    2964             : 
    2965           0 :                 if (i == needle_len) {
    2966           0 :                         return (const char *)p;
    2967             :                 }
    2968             :                 
    2969           0 :                 if (UNEXPECTED(p == haystack)) {
    2970           0 :                         return NULL;
    2971             :                 }
    2972             : 
    2973           0 :                 p -= td[(unsigned char)(p[-1])];
    2974             :         }
    2975             : 
    2976           0 :         return NULL;
    2977             : }
    2978             : /* }}} */
    2979             : 
    2980             : #if !ZEND_DVAL_TO_LVAL_CAST_OK
    2981             : # if SIZEOF_ZEND_LONG == 4
    2982             : ZEND_API zend_long ZEND_FASTCALL zend_dval_to_lval_slow(double d)
    2983             : {
    2984             :         double  two_pow_32 = pow(2., 32.),
    2985             :                         dmod;
    2986             : 
    2987             :         dmod = fmod(d, two_pow_32);
    2988             :         if (dmod < 0) {
    2989             :                 /* we're going to make this number positive; call ceil()
    2990             :                  * to simulate rounding towards 0 of the negative number */
    2991             :                 dmod = ceil(dmod);// + two_pow_32;
    2992             :         }
    2993             :         return (zend_long)(zend_ulong)dmod;
    2994             : }
    2995             : #else
    2996         140 : ZEND_API zend_long ZEND_FASTCALL zend_dval_to_lval_slow(double d)
    2997             : {
    2998         140 :         double  two_pow_64 = pow(2., 64.),
    2999             :                         dmod;
    3000             : 
    3001         140 :         dmod = fmod(d, two_pow_64);
    3002         140 :         if (dmod < 0) {
    3003             :                 /* no need to call ceil; original double must have had no
    3004             :                  * fractional part, hence dmod does not have one either */
    3005           7 :                 dmod += two_pow_64;
    3006             :         }
    3007         140 :         return (zend_long)(zend_ulong)dmod;
    3008             : }
    3009             : #endif
    3010             : #endif
    3011             : 
    3012             : /*
    3013             :  * Local variables:
    3014             :  * tab-width: 4
    3015             :  * c-basic-offset: 4
    3016             :  * indent-tabs-mode: t
    3017             :  * End:
    3018             :  */

Generated by: LCOV version 1.10

Generated at Sun, 18 Sep 2016 08:20:03 +0000 (7 days ago)

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