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: 1191 1398 85.2 %
Date: 2016-07-19 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       70726 : ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, int str_len) /* {{{ */
      84             : {
      85             :         int retval;
      86             : 
      87       70726 :         if (!str_len) {
      88       46782 :                 str_len = (int)strlen(str);
      89             :         }
      90       70726 :         retval = ZEND_STRTOL(str, NULL, 0);
      91       70726 :         if (str_len>0) {
      92       47343 :                 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       70726 :         return retval;
     108             : }
     109             : /* }}} */
     110             : 
     111     1544034 : ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, int str_len) /* {{{ */
     112             : {
     113             :         zend_long retval;
     114             : 
     115     1544034 :         if (!str_len) {
     116       23253 :                 str_len = (int)strlen(str);
     117             :         }
     118     1544034 :         retval = ZEND_STRTOL(str, NULL, 0);
     119     1544034 :         if (str_len>0) {
     120     1520781 :                 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       70188 :                                 retval *= 1024;
     128             :                                 /* break intentionally missing */
     129             :                         case 'k':
     130             :                         case 'K':
     131       93598 :                                 retval *= 1024;
     132             :                                 break;
     133             :                 }
     134             :         }
     135     1544034 :         return retval;
     136             : }
     137             : /* }}} */
     138             : 
     139      203354 : void ZEND_FASTCALL _convert_scalar_to_number(zval *op, zend_bool silent) /* {{{ */
     140             : {
     141             : try_again:
     142      203354 :         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      101123 :                                 str = Z_STR_P(op);
     151      202246 :                                 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          53 :                                         ZVAL_LONG(op, 0);
     153          53 :                                         if (!silent) {
     154           6 :                                                 zend_error(E_WARNING, "A non-numeric value encountered");
     155             :                                         }
     156             :                                 }
     157             :                                 zend_string_release(str);
     158      101123 :                                 break;
     159             :                         }
     160             :                 case IS_NULL:
     161             :                 case IS_FALSE:
     162          61 :                         ZVAL_LONG(op, 0);
     163          61 :                         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      203350 : }
     179             : /* }}} */
     180             : 
     181      203306 : ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op) /* {{{ */
     182             : {
     183      203306 :         _convert_scalar_to_number(op, 1);
     184      203306 : }
     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       18755 : ZEND_API void ZEND_FASTCALL convert_to_long(zval *op) /* {{{ */
     284             : {
     285       18755 :         if (Z_TYPE_P(op) != IS_LONG) {
     286         459 :                 convert_to_long_base(op, 10);
     287             :         }
     288       18755 : }
     289             : /* }}} */
     290             : 
     291         472 : ZEND_API void ZEND_FASTCALL convert_to_long_base(zval *op, int base) /* {{{ */
     292             : {
     293             :         zend_long tmp;
     294             : 
     295             : try_again:
     296         472 :         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         212 :                         ZVAL_LONG(op, zend_dval_to_lval(Z_DVAL_P(op)));
     313         106 :                         break;
     314             :                 case IS_STRING:
     315             :                         {
     316         133 :                                 zend_string *str = Z_STR_P(op);
     317         133 :                                 if (base == 10) {
     318         266 :                                         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         133 :                         break;
     325             :                 case IS_ARRAY:
     326          32 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     327          32 :                         zval_ptr_dtor(op);
     328          32 :                         ZVAL_LONG(op, tmp);
     329          32 :                         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        3038 : ZEND_API void ZEND_FASTCALL convert_to_double(zval *op) /* {{{ */
     354             : {
     355             :         double tmp;
     356             : 
     357             : try_again:
     358        3038 :         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          48 :                                 zend_string *str = Z_STR_P(op);
     380             : 
     381          48 :                                 ZVAL_DOUBLE(op, zend_strtod(ZSTR_VAL(str), NULL));
     382             :                                 zend_string_release(str);
     383             :                         }
     384          48 :                         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        3038 : }
     410             : /* }}} */
     411             : 
     412         914 : ZEND_API void ZEND_FASTCALL convert_to_null(zval *op) /* {{{ */
     413             : {
     414         914 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     415           3 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     416             :                         zval org;
     417             : 
     418           3 :                         ZVAL_COPY_VALUE(&org, op);
     419           3 :                         if (Z_OBJ_HT_P(op)->cast_object(&org, op, IS_NULL) == SUCCESS) {
     420             :                                 zval_dtor(&org);
     421           0 :                                 return;
     422             :                         }
     423           3 :                         ZVAL_COPY_VALUE(op, &org);
     424             :                 }
     425             :         }
     426             : 
     427         914 :         zval_ptr_dtor(op);
     428         914 :         ZVAL_NULL(op);
     429             : }
     430             : /* }}} */
     431             : 
     432         352 : ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */
     433             : {
     434             :         int tmp;
     435             : 
     436             : try_again:
     437         352 :         switch (Z_TYPE_P(op)) {
     438             :                 case IS_FALSE:
     439             :                 case IS_TRUE:
     440         231 :                         break;
     441             :                 case IS_NULL:
     442           5 :                         ZVAL_FALSE(op);
     443           5 :                         break;
     444             :                 case IS_RESOURCE: {
     445           7 :                                 zend_long l = (Z_RES_HANDLE_P(op) ? 1 : 0);
     446             : 
     447           7 :                                 zval_ptr_dtor(op);
     448           7 :                                 ZVAL_BOOL(op, l);
     449             :                         }
     450           7 :                         break;
     451             :                 case IS_LONG:
     452          73 :                         ZVAL_BOOL(op, Z_LVAL_P(op) ? 1 : 0);
     453          73 :                         break;
     454             :                 case IS_DOUBLE:
     455           6 :                         ZVAL_BOOL(op, Z_DVAL_P(op) ? 1 : 0);
     456           6 :                         break;
     457             :                 case IS_STRING:
     458             :                         {
     459          17 :                                 zend_string *str = Z_STR_P(op);
     460             : 
     461          37 :                                 if (ZSTR_LEN(str) == 0
     462          36 :                                         || (ZSTR_LEN(str) == 1 && ZSTR_VAL(str)[0] == '0')) {
     463           1 :                                         ZVAL_FALSE(op);
     464             :                                 } else {
     465          16 :                                         ZVAL_TRUE(op);
     466             :                                 }
     467             :                                 zend_string_release(str);
     468             :                         }
     469          17 :                         break;
     470             :                 case IS_ARRAY:
     471           8 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     472           8 :                         zval_ptr_dtor(op);
     473           8 :                         ZVAL_BOOL(op, tmp);
     474           8 :                         break;
     475             :                 case IS_OBJECT:
     476             :                         {
     477             :                                 zval dst;
     478             : 
     479           5 :                                 convert_object_to_type(op, &dst, _IS_BOOL, convert_to_boolean);
     480             :                                 zval_dtor(op);
     481             : 
     482          15 :                                 if (Z_TYPE(dst) == IS_FALSE || Z_TYPE(dst) == IS_TRUE) {
     483           5 :                                         ZVAL_COPY_VALUE(op, &dst);
     484             :                                 } else {
     485           0 :                                         ZVAL_TRUE(op);
     486             :                                 }
     487           5 :                                 break;
     488             :                         }
     489             :                 case IS_REFERENCE:
     490             :                         zend_unwrap_reference(op);
     491           0 :                         goto try_again;
     492             :                 EMPTY_SWITCH_DEFAULT_CASE()
     493             :         }
     494         352 : }
     495             : /* }}} */
     496             : 
     497          13 : ZEND_API void ZEND_FASTCALL _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     498             : {
     499          13 :         if (Z_TYPE_P(op) == IS_DOUBLE) {
     500             :                 zend_string *str;
     501           1 :                 double dval = Z_DVAL_P(op);
     502             : 
     503           1 :                 str = zend_strpprintf(0, "%.*H", (int) EG(precision), dval);
     504           1 :                 ZVAL_NEW_STR(op, str);
     505             :         } else {
     506          12 :                 _convert_to_string(op ZEND_FILE_LINE_CC);
     507             :         }
     508          13 : }
     509             : /* }}} */
     510             : 
     511       72353 : ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     512             : {
     513             : try_again:
     514       72353 :         switch (Z_TYPE_P(op)) {
     515             :                 case IS_UNDEF:
     516             :                 case IS_NULL:
     517             :                 case IS_FALSE: {
     518        4272 :                         ZVAL_EMPTY_STRING(op);
     519        4272 :                         break;
     520             :                 }
     521             :                 case IS_TRUE:
     522         785 :                         if (CG(one_char_string)['1']) {
     523           0 :                                 ZVAL_INTERNED_STR(op, CG(one_char_string)['1']);
     524             :                         } else {
     525        1570 :                                 ZVAL_NEW_STR(op, zend_string_init("1", 1, 0));
     526             :                         }
     527         785 :                         break;
     528             :                 case IS_STRING:
     529           3 :                         break;
     530             :                 case IS_RESOURCE: {
     531             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     532          43 :                         int len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
     533          43 :                         zval_ptr_dtor(op);
     534          86 :                         ZVAL_NEW_STR(op, zend_string_init(buf, len, 0));
     535          43 :                         break;
     536             :                 }
     537             :                 case IS_LONG: {
     538       65095 :                         ZVAL_NEW_STR(op, zend_long_to_str(Z_LVAL_P(op)));
     539       65095 :                         break;
     540             :                 }
     541             :                 case IS_DOUBLE: {
     542             :                         zend_string *str;
     543        1942 :                         double dval = Z_DVAL_P(op);
     544             : 
     545        1942 :                         str = zend_strpprintf(0, "%.*G", (int) EG(precision), dval);
     546             :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     547        1942 :                         ZVAL_NEW_STR(op, str);
     548        1942 :                         break;
     549             :                 }
     550             :                 case IS_ARRAY:
     551         168 :                         zend_error(E_NOTICE, "Array to string conversion");
     552         168 :                         zval_ptr_dtor(op);
     553         336 :                         ZVAL_NEW_STR(op, zend_string_init("Array", sizeof("Array")-1, 0));
     554         168 :                         break;
     555             :                 case IS_OBJECT: {
     556             :                         zval dst;
     557             : 
     558          42 :                         convert_object_to_type(op, &dst, IS_STRING, convert_to_string);
     559             :                         zval_dtor(op);
     560             : 
     561          34 :                         if (Z_TYPE(dst) == IS_STRING) {
     562          29 :                                 ZVAL_COPY_VALUE(op, &dst);
     563             :                         } else {
     564          10 :                                 ZVAL_NEW_STR(op, zend_string_init("Object", sizeof("Object")-1, 0));
     565             :                         }
     566          34 :                         break;
     567             :                 }
     568             :                 case IS_REFERENCE:
     569             :                         zend_unwrap_reference(op);
     570           3 :                         goto try_again;
     571             :                 EMPTY_SWITCH_DEFAULT_CASE()
     572             :         }
     573       72342 : }
     574             : /* }}} */
     575             : 
     576         120 : static void convert_scalar_to_array(zval *op) /* {{{ */
     577             : {
     578             :         zval entry;
     579             : 
     580         120 :         ZVAL_COPY_VALUE(&entry, op);
     581             : 
     582         120 :         ZVAL_NEW_ARR(op);
     583         120 :         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     584         120 :         zend_hash_index_add_new(Z_ARRVAL_P(op), 0, &entry);
     585         120 : }
     586             : /* }}} */
     587             : 
     588         217 : ZEND_API void ZEND_FASTCALL convert_to_array(zval *op) /* {{{ */
     589             : {
     590             : try_again:
     591         217 :         switch (Z_TYPE_P(op)) {
     592             :                 case IS_ARRAY:
     593          49 :                         break;
     594             : /* OBJECTS_OPTIMIZE */
     595             :                 case IS_OBJECT:
     596          30 :                         if (Z_OBJCE_P(op) == zend_ce_closure) {
     597           3 :                                 convert_scalar_to_array(op);
     598             :                         } else {
     599          27 :                                 if (Z_OBJ_HT_P(op)->get_properties) {
     600          27 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op);
     601          27 :                                         if (obj_ht) {
     602             :                                                 zend_array *arr;
     603             : 
     604          82 :                                                 if (!Z_OBJCE_P(op)->default_properties_count &&
     605          22 :                                                         obj_ht == Z_OBJ_P(op)->properties &&
     606          17 :                                                         !ZEND_HASH_GET_APPLY_COUNT(Z_OBJ_P(op)->properties)) {
     607             :                                                         /* fast copy */
     608          16 :                                                         if (EXPECTED(Z_OBJ_P(op)->handlers == &std_object_handlers)) {
     609          14 :                                                                 arr = obj_ht;
     610          14 :                                                                 if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(op)->properties) & IS_ARRAY_IMMUTABLE))) {
     611          14 :                                                                         GC_REFCOUNT(Z_OBJ_P(op)->properties)++;
     612             :                                                                 }
     613             :                                                         } else {
     614           2 :                                                                 arr = zend_array_dup(obj_ht);
     615             :                                                         }
     616             :                                                         zval_dtor(op);
     617          16 :                                                         ZVAL_ARR(op, arr);
     618             :                                                 } else {
     619          11 :                                                         arr = zend_array_dup(obj_ht);
     620             :                                                         zval_dtor(op);
     621          11 :                                                         ZVAL_ARR(op, arr);
     622             :                                                 }
     623          27 :                                                 return;
     624             :                                         }
     625             :                                 } else {
     626             :                                         zval dst;
     627           0 :                                         convert_object_to_type(op, &dst, IS_ARRAY, convert_to_array);
     628             : 
     629           0 :                                         if (Z_TYPE(dst) == IS_ARRAY) {
     630             :                                                 zval_dtor(op);
     631           0 :                                                 ZVAL_COPY_VALUE(op, &dst);
     632           0 :                                                 return;
     633             :                                         }
     634             :                                 }
     635             : 
     636             :                                 zval_dtor(op);
     637           0 :                                 array_init(op);
     638             :                         }
     639           3 :                         break;
     640             :                 case IS_NULL:
     641          21 :                         ZVAL_NEW_ARR(op);
     642          21 :                         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     643          21 :                         break;
     644             :                 case IS_REFERENCE:
     645             :                         zend_unwrap_reference(op);
     646           0 :                         goto try_again;
     647             :                 default:
     648         117 :                         convert_scalar_to_array(op);
     649             :                         break;
     650             :         }
     651             : }
     652             : /* }}} */
     653             : 
     654         136 : ZEND_API void ZEND_FASTCALL convert_to_object(zval *op) /* {{{ */
     655             : {
     656             : try_again:
     657         136 :         switch (Z_TYPE_P(op)) {
     658             :                 case IS_ARRAY:
     659             :                         {
     660          92 :                                 HashTable *ht = Z_ARR_P(op);
     661          92 :                                 if (Z_IMMUTABLE_P(op)) {
     662             :                                         /* TODO: try not to duplicate immutable arrays as well ??? */
     663           0 :                                         ht = zend_array_dup(ht);
     664             :                                 }
     665          92 :                                 object_and_properties_init(op, zend_standard_class_def, ht);
     666          92 :                                 break;
     667             :                         }
     668             :                 case IS_OBJECT:
     669           3 :                         break;
     670             :                 case IS_NULL:
     671           3 :                         object_init(op);
     672           3 :                         break;
     673             :                 case IS_REFERENCE:
     674             :                         zend_unwrap_reference(op);
     675           0 :                         goto try_again;
     676             :                 default: {
     677             :                         zval tmp;
     678          38 :                         ZVAL_COPY_VALUE(&tmp, op);
     679          38 :                         object_init(op);
     680          38 :                         zend_hash_add_new(Z_OBJPROP_P(op), CG(known_strings)[ZEND_STR_SCALAR], &tmp);
     681             :                         break;
     682             :                 }
     683             :         }
     684         136 : }
     685             : /* }}} */
     686             : 
     687           0 : ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
     688             : {
     689             :         zval *arg;
     690             :         va_list ap;
     691             : 
     692           0 :         va_start(ap, argc);
     693             : 
     694           0 :         while (argc--) {
     695           0 :                 arg = va_arg(ap, zval *);
     696           0 :                 convert_to_long_ex(arg);
     697             :         }
     698             : 
     699           0 :         va_end(ap);
     700           0 : }
     701             : /* }}} */
     702             : 
     703           0 : ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
     704             : {
     705             :         zval *arg;
     706             :         va_list ap;
     707             : 
     708           0 :         va_start(ap, argc);
     709             : 
     710           0 :         while (argc--) {
     711           0 :                 arg = va_arg(ap, zval *);
     712           0 :                 convert_to_double_ex(arg);
     713             :         }
     714             : 
     715           0 :         va_end(ap);
     716           0 : }
     717             : /* }}} */
     718             : 
     719           0 : ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
     720             : {
     721             :         zval *arg;
     722             :         va_list ap;
     723             : 
     724           0 :         va_start(ap, argc);
     725             : 
     726           0 :         while (argc--) {
     727           0 :                 arg = va_arg(ap, zval *);
     728           0 :                 convert_to_string_ex(arg);
     729             :         }
     730             : 
     731           0 :         va_end(ap);
     732           0 : }
     733             : /* }}} */
     734             : 
     735             : static zend_always_inline zend_long ZEND_FASTCALL _zval_get_long_func_ex(zval *op, zend_bool silent) /* {{{ */
     736             : {
     737             : try_again:
     738       16420 :         switch (Z_TYPE_P(op)) {
     739             :                 case IS_UNDEF:
     740             :                 case IS_NULL:
     741             :                 case IS_FALSE:
     742        1021 :                         return 0;
     743             :                 case IS_TRUE:
     744        3015 :                         return 1;
     745             :                 case IS_RESOURCE:
     746         110 :                         return Z_RES_HANDLE_P(op);
     747             :                 case IS_LONG:
     748           1 :                         return Z_LVAL_P(op);
     749             :                 case IS_DOUBLE:
     750        7368 :                         return zend_dval_to_lval(Z_DVAL_P(op));
     751             :                 case IS_STRING:
     752             :                         {
     753             :                                 zend_uchar type;
     754             :                                 zend_long lval;
     755             :                                 double dval;
     756       15418 :                                 if (0 == (type = is_numeric_string(Z_STRVAL_P(op), Z_STRLEN_P(op), &lval, &dval, silent ? 1 : -1))) {
     757        1201 :                                         if (!silent) {
     758         198 :                                                 zend_error(E_WARNING, "A non-numeric value encountered");
     759             :                                         }
     760        1201 :                                         return 0;
     761        6508 :                                 } else if (EXPECTED(type == IS_LONG)) {
     762        6051 :                                         return lval;
     763             :                                 } else {
     764             :                                         /* Previously we used strtol here, not is_numeric_string,
     765             :                                          * and strtol gives you LONG_MAX/_MIN on overflow.
     766             :                                          * We use use saturating conversion to emulate strtol()'s
     767             :                                          * behaviour.
     768             :                                          */
     769         914 :                                          return zend_dval_to_lval_cap(dval);
     770             :                                 }
     771             :                         }
     772             :                 case IS_ARRAY:
     773         848 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1 : 0;
     774             :                 case IS_OBJECT:
     775             :                         {
     776             :                                 zval dst;
     777          26 :                                 convert_object_to_type(op, &dst, IS_LONG, convert_to_long);
     778          26 :                                 if (Z_TYPE(dst) == IS_LONG) {
     779          26 :                                         return Z_LVAL(dst);
     780             :                                 } else {
     781           0 :                                         return 1;
     782             :                                 }
     783             :                         }
     784             :                 case IS_REFERENCE:
     785           6 :                         op = Z_REFVAL_P(op);
     786             :                         goto try_again;
     787             :                 EMPTY_SWITCH_DEFAULT_CASE()
     788             :         }
     789           0 :         return 0;
     790             : }
     791             : /* }}} */
     792             : 
     793       14689 : ZEND_API zend_long ZEND_FASTCALL _zval_get_long_func(zval *op) /* {{{ */
     794             : {
     795       14689 :         return _zval_get_long_func_ex(op, 1);
     796             : }
     797             : /* }}} */
     798             : 
     799        1725 : static zend_long ZEND_FASTCALL _zval_get_long_func_noisy(zval *op) /* {{{ */
     800             : {
     801        1725 :         return _zval_get_long_func_ex(op, 0);
     802             : }
     803             : /* }}} */
     804             : 
     805        5039 : ZEND_API double ZEND_FASTCALL _zval_get_double_func(zval *op) /* {{{ */
     806             : {
     807             : try_again:
     808        5039 :         switch (Z_TYPE_P(op)) {
     809             :                 case IS_NULL:
     810             :                 case IS_FALSE:
     811         106 :                         return 0.0;
     812             :                 case IS_TRUE:
     813         113 :                         return 1.0;
     814             :                 case IS_RESOURCE:
     815          41 :                         return (double) Z_RES_HANDLE_P(op);
     816             :                 case IS_LONG:
     817        3823 :                         return (double) Z_LVAL_P(op);
     818             :                 case IS_DOUBLE:
     819           0 :                         return Z_DVAL_P(op);
     820             :                 case IS_STRING:
     821         577 :                         return zend_strtod(Z_STRVAL_P(op), NULL);
     822             :                 case IS_ARRAY:
     823         357 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1.0 : 0.0;
     824             :                 case IS_OBJECT:
     825             :                         {
     826             :                                 zval dst;
     827          10 :                                 convert_object_to_type(op, &dst, IS_DOUBLE, convert_to_double);
     828             : 
     829          10 :                                 if (Z_TYPE(dst) == IS_DOUBLE) {
     830          10 :                                         return Z_DVAL(dst);
     831             :                                 } else {
     832           0 :                                         return 1.0;
     833             :                                 }
     834             :                         }
     835             :                 case IS_REFERENCE:
     836          12 :                         op = Z_REFVAL_P(op);
     837          12 :                         goto try_again;
     838             :                 EMPTY_SWITCH_DEFAULT_CASE()
     839             :         }
     840           0 :         return 0.0;
     841             : }
     842             : /* }}} */
     843             : 
     844     2918527 : ZEND_API zend_string* ZEND_FASTCALL _zval_get_string_func(zval *op) /* {{{ */
     845             : {
     846             : try_again:
     847     2918527 :         switch (Z_TYPE_P(op)) {
     848             :                 case IS_UNDEF:
     849             :                 case IS_NULL:
     850             :                 case IS_FALSE:
     851     1374623 :                         return ZSTR_EMPTY_ALLOC();
     852             :                 case IS_TRUE:
     853        1375 :                         if (CG(one_char_string)['1']) {
     854           0 :                                 return CG(one_char_string)['1'];
     855             :                         } else {
     856        1375 :                                 return zend_string_init("1", 1, 0);
     857             :                         }
     858             :                 case IS_RESOURCE: {
     859             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     860             :                         int len;
     861             : 
     862         642 :                         len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
     863        1284 :                         return zend_string_init(buf, len, 0);
     864             :                 }
     865             :                 case IS_LONG: {
     866      414427 :                         return zend_long_to_str(Z_LVAL_P(op));
     867             :                 }
     868             :                 case IS_DOUBLE: {
     869        6044 :                         return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
     870             :                 }
     871             :                 case IS_ARRAY:
     872         771 :                         zend_error(E_NOTICE, "Array to string conversion");
     873         771 :                         return zend_string_init("Array", sizeof("Array")-1, 0);
     874             :                 case IS_OBJECT: {
     875             :                         zval tmp;
     876      103675 :                         if (Z_OBJ_HT_P(op)->cast_object) {
     877      103675 :                                 if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_STRING) == SUCCESS) {
     878      103636 :                                         return Z_STR(tmp);
     879             :                                 }
     880           0 :                         } else if (Z_OBJ_HT_P(op)->get) {
     881           0 :                                 zval *z = Z_OBJ_HT_P(op)->get(op, &tmp);
     882           0 :                                 if (Z_TYPE_P(z) != IS_OBJECT) {
     883           0 :                                         zend_string *str = zval_get_string(z);
     884           0 :                                         zval_ptr_dtor(z);
     885           0 :                                         return str;
     886             :                                 }
     887           0 :                                 zval_ptr_dtor(z);
     888             :                         }
     889          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));
     890          29 :                         return ZSTR_EMPTY_ALLOC();
     891             :                 }
     892             :                 case IS_REFERENCE:
     893      516619 :                         op = Z_REFVAL_P(op);
     894      516619 :                         goto try_again;
     895             :                 case IS_STRING:
     896     1000702 :                         return zend_string_copy(Z_STR_P(op));
     897             :                 EMPTY_SWITCH_DEFAULT_CASE()
     898             :         }
     899           0 :         return NULL;
     900             : }
     901             : /* }}} */
     902             : 
     903     1824609 : ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {{{ */
     904             : {
     905             :         zval op1_copy, op2_copy;
     906     1824609 :         int converted = 0;
     907             : 
     908             :         while (1) {
     909     3650232 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     910             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
     911             :                                 fast_long_add_function(result, op1, op2);
     912      877185 :                                 return SUCCESS;
     913             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     914          57 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     915          57 :                                 return SUCCESS;
     916             : 
     917             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     918          62 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     919          62 :                                 return SUCCESS;
     920             : 
     921             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     922      947262 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     923      947262 :                                 return SUCCESS;
     924             : 
     925             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
     926          31 :                                 if ((result == op1) && (result == op2)) {
     927             :                                         /* $a += $a */
     928           1 :                                         return SUCCESS;
     929             :                                 }
     930          30 :                                 if (result != op1) {
     931          28 :                                         ZVAL_DUP(result, op1);
     932             :                                 }
     933          30 :                                 zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0);
     934          30 :                                 return SUCCESS;
     935             : 
     936             :                         default:
     937         519 :                                 if (Z_ISREF_P(op1)) {
     938          24 :                                         op1 = Z_REFVAL_P(op1);
     939         495 :                                 } else if (Z_ISREF_P(op2)) {
     940          18 :                                         op2 = Z_REFVAL_P(op2);
     941         477 :                                 } else if (!converted) {
     942        1404 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function);
     943             : 
     944        1251 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
     945        1172 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
     946         465 :                                         converted = 1;
     947             :                                 } else {
     948           8 :                                         zend_throw_error(NULL, "Unsupported operand types");
     949           8 :                                         return FAILURE; /* unknown datatype */
     950             :                                 }
     951             :                 }
     952         507 :         }
     953             : }
     954             : /* }}} */
     955             : 
     956     2898278 : ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {{{ */
     957             : {
     958             :         zval op1_copy, op2_copy;
     959     2898278 :         int converted = 0;
     960             : 
     961             :         while (1) {
     962    17163440 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     963             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
     964             :                                 fast_long_sub_function(result, op1, op2);
     965     2898130 :                                 return SUCCESS;
     966             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     967          57 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     968          57 :                                 return SUCCESS;
     969             : 
     970             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     971          45 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     972          45 :                                 return SUCCESS;
     973             : 
     974             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     975          38 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     976          38 :                                 return SUCCESS;
     977             : 
     978             :                         default:
     979     5683450 :                                 if (Z_ISREF_P(op1)) {
     980     2841608 :                                         op1 = Z_REFVAL_P(op1);
     981     2841842 :                                 } else if (Z_ISREF_P(op2)) {
     982     2841607 :                                         op2 = Z_REFVAL_P(op2);
     983         235 :                                 } else if (!converted) {
     984         690 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function);
     985             : 
     986         673 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
     987         661 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
     988         227 :                                         converted = 1;
     989             :                                 } else {
     990           4 :                                         zend_throw_error(NULL, "Unsupported operand types");
     991           2 :                                         return FAILURE; /* unknown datatype */
     992             :                                 }
     993             :                 }
     994     5683442 :         }
     995             : }
     996             : /* }}} */
     997             : 
     998        7303 : ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2) /* {{{ */
     999             : {
    1000             :         zval op1_copy, op2_copy;
    1001        7303 :         int converted = 0;
    1002             : 
    1003             :         while (1) {
    1004       15108 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1005             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
    1006             :                                 zend_long overflow;
    1007             : 
    1008        5409 :                                 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
    1009        5409 :                                 Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
    1010        5409 :                                 return SUCCESS;
    1011             : 
    1012             :                         }
    1013             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1014        1785 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
    1015        1785 :                                 return SUCCESS;
    1016             : 
    1017             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1018          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
    1019          61 :                                 return SUCCESS;
    1020             : 
    1021             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1022          39 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
    1023          39 :                                 return SUCCESS;
    1024             : 
    1025             :                         default:
    1026         260 :                                 if (Z_ISREF_P(op1)) {
    1027           4 :                                         op1 = Z_REFVAL_P(op1);
    1028         256 :                                 } else if (Z_ISREF_P(op2)) {
    1029           4 :                                         op2 = Z_REFVAL_P(op2);
    1030         252 :                                 } else if (!converted) {
    1031         747 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function);
    1032             : 
    1033         707 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
    1034         706 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
    1035         243 :                                         converted = 1;
    1036             :                                 } else {
    1037           2 :                                         zend_throw_error(NULL, "Unsupported operand types");
    1038           2 :                                         return FAILURE; /* unknown datatype */
    1039             :                                 }
    1040             :                 }
    1041         251 :         }
    1042             : }
    1043             : /* }}} */
    1044             : 
    1045     2843838 : ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1046             : {
    1047             :         zval op1_copy, op2_copy;
    1048     2843838 :         int converted = 0;
    1049             : 
    1050             :         while (1) {
    1051     5687824 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1052             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1053     2843120 :                                 if (Z_LVAL_P(op2) >= 0) {
    1054     2842437 :                                         zend_long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
    1055             : 
    1056     2842437 :                                         if (i == 0) {
    1057          28 :                                                 ZVAL_LONG(result, 1L);
    1058          28 :                                                 return SUCCESS;
    1059     2842409 :                                         } else if (l2 == 0) {
    1060     2841614 :                                                 ZVAL_LONG(result, 0);
    1061     2841614 :                                                 return SUCCESS;
    1062             :                                         }
    1063             : 
    1064        6679 :                                         while (i >= 1) {
    1065             :                                                 zend_long overflow;
    1066        5181 :                                                 double dval = 0.0;
    1067             : 
    1068        5181 :                                                 if (i % 2) {
    1069        2013 :                                                         --i;
    1070        2013 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
    1071        2013 :                                                         if (overflow) {
    1072          17 :                                                                 ZVAL_DOUBLE(result, dval * pow(l2, i));
    1073          17 :                                                                 return SUCCESS;
    1074             :                                                         }
    1075             :                                                 } else {
    1076        3168 :                                                         i /= 2;
    1077        3168 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
    1078        3168 :                                                         if (overflow) {
    1079          75 :                                                                 ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
    1080          75 :                                                                 return SUCCESS;
    1081             :                                                         }
    1082             :                                                 }
    1083             :                                         }
    1084             :                                         /* i == 0 */
    1085         703 :                                         ZVAL_LONG(result, l1);
    1086             :                                 } else {
    1087         683 :                                         ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
    1088             :                                 }
    1089        1386 :                                 return SUCCESS;
    1090             : 
    1091             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1092         501 :                                 ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
    1093         501 :                                 return SUCCESS;
    1094             : 
    1095             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1096         147 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
    1097         147 :                                 return SUCCESS;
    1098             : 
    1099             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1100          65 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
    1101          65 :                                 return SUCCESS;
    1102             : 
    1103             :                         default:
    1104          79 :                                 if (Z_ISREF_P(op1)) {
    1105           0 :                                         op1 = Z_REFVAL_P(op1);
    1106          79 :                                 } else if (Z_ISREF_P(op2)) {
    1107           1 :                                         op2 = Z_REFVAL_P(op2);
    1108          78 :                                 } else if (!converted) {
    1109         232 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW, pow_function);
    1110             : 
    1111          75 :                                         if (Z_TYPE_P(op1) == IS_ARRAY) {
    1112           1 :                                                 ZVAL_LONG(result, 0);
    1113           1 :                                                 return SUCCESS;
    1114             :                                         } else {
    1115         195 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
    1116             :                                         }
    1117          74 :                                         if (Z_TYPE_P(op2) == IS_ARRAY) {
    1118           1 :                                                 ZVAL_LONG(result, 1L);
    1119           1 :                                                 return SUCCESS;
    1120             :                                         } else {
    1121         156 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
    1122             :                                         }
    1123          73 :                                         converted = 1;
    1124             :                                 } else {
    1125           0 :                                         zend_throw_error(NULL, "Unsupported operand types");
    1126           0 :                                         return FAILURE;
    1127             :                                 }
    1128             :                 }
    1129          74 :         }
    1130             : }
    1131             : /* }}} */
    1132             : 
    1133      127134 : ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1134             : {
    1135             :         zval op1_copy, op2_copy;
    1136      127134 :         int converted = 0;
    1137             : 
    1138             :         while (1) {
    1139      254696 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1140             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1141      118428 :                                 if (Z_LVAL_P(op2) == 0) {
    1142          47 :                                         zend_error(E_WARNING, "Division by zero");
    1143          47 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1) / (double) Z_LVAL_P(op2)));
    1144          47 :                                         return SUCCESS;
    1145      118381 :                                 } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN) {
    1146             :                                         /* Prevent overflow error/crash */
    1147           1 :                                         ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
    1148           1 :                                         return SUCCESS;
    1149             :                                 }
    1150      118380 :                                 if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
    1151       78540 :                                         ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
    1152             :                                 } else {
    1153       39840 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
    1154             :                                 }
    1155      118380 :                                 return SUCCESS;
    1156             : 
    1157             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1158        8571 :                                 if (Z_LVAL_P(op2) == 0) {
    1159          17 :                                         zend_error(E_WARNING, "Division by zero");
    1160             :                                 }
    1161        8571 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
    1162        8571 :                                 return SUCCESS;
    1163             : 
    1164             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1165          67 :                                 if (Z_DVAL_P(op2) == 0) {
    1166           1 :                                         zend_error(E_WARNING, "Division by zero");
    1167             :                                 }
    1168          67 :                                 ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
    1169          67 :                                 return SUCCESS;
    1170             : 
    1171             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1172          62 :                                 if (Z_DVAL_P(op2) == 0) {
    1173           1 :                                         zend_error(E_WARNING, "Division by zero");
    1174             :                                 }
    1175          62 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
    1176          62 :                                 return SUCCESS;
    1177             : 
    1178             :                         default:
    1179         220 :                                 if (Z_ISREF_P(op1)) {
    1180           0 :                                         op1 = Z_REFVAL_P(op1);
    1181         220 :                                 } else if (Z_ISREF_P(op2)) {
    1182           7 :                                         op2 = Z_REFVAL_P(op2);
    1183         213 :                                 } else if (!converted) {
    1184         630 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function);
    1185             : 
    1186         615 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result, 0);
    1187         615 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result, 0);
    1188         207 :                                         converted = 1;
    1189             :                                 } else {
    1190           2 :                                         zend_throw_error(NULL, "Unsupported operand types");
    1191           2 :                                         return FAILURE; /* unknown datatype */
    1192             :                                 }
    1193             :                 }
    1194         214 :         }
    1195             : }
    1196             : /* }}} */
    1197             : 
    1198         358 : ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1199             : {
    1200             :         zend_long op1_lval, op2_lval;
    1201             : 
    1202        2365 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function);
    1203             : 
    1204         354 :         if (op1 == result) {
    1205             :                 zval_dtor(result);
    1206             :         }
    1207             : 
    1208         354 :         if (op2_lval == 0) {
    1209             :                 /* modulus by zero */
    1210          98 :                 if (EG(current_execute_data) && !CG(in_compilation)) {
    1211          49 :                         zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
    1212             :                 } else {
    1213           0 :                         zend_error_noreturn(E_ERROR, "Modulo by zero");
    1214             :                 }
    1215          49 :                 ZVAL_UNDEF(result);
    1216          49 :                 return FAILURE;
    1217             :         }
    1218             : 
    1219         305 :         if (op2_lval == -1) {
    1220             :                 /* Prevent overflow error/crash if op1==LONG_MIN */
    1221           6 :                 ZVAL_LONG(result, 0);
    1222           6 :                 return SUCCESS;
    1223             :         }
    1224             : 
    1225         299 :         ZVAL_LONG(result, op1_lval % op2_lval);
    1226         299 :         return SUCCESS;
    1227             : }
    1228             : /* }}} */
    1229             : 
    1230           2 : ZEND_API int ZEND_FASTCALL boolean_xor_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1231             : {
    1232             :         int op1_val, op2_val;
    1233             : 
    1234             :         do {
    1235           2 :                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1236           0 :                         op1_val = 0;
    1237           2 :                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1238           0 :                         op1_val = 1;
    1239             :                 } else {
    1240           2 :                         if (Z_ISREF_P(op1)) {
    1241           0 :                                 op1 = Z_REFVAL_P(op1);
    1242           0 :                                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1243           0 :                                         op1_val = 0;
    1244           0 :                                         break;
    1245           0 :                                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1246           0 :                                         op1_val = 1;
    1247           0 :                                         break;
    1248             :                                 }
    1249             :                         }
    1250           4 :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BOOL_XOR, boolean_xor_function);
    1251           2 :                         op1_val = zval_is_true(op1);
    1252             :                 }
    1253             :         } while (0);
    1254             :         do {
    1255           2 :                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1256           0 :                         op2_val = 0;
    1257           2 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1258           0 :                         op2_val = 1;
    1259             :                 } else {
    1260           2 :                         if (Z_ISREF_P(op2)) {
    1261           0 :                                 op2 = Z_REFVAL_P(op2);
    1262           0 :                                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1263           0 :                                         op2_val = 0;
    1264           0 :                                         break;
    1265           0 :                                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1266           0 :                                         op2_val = 1;
    1267           0 :                                         break;
    1268             :                                 }
    1269             :                         }
    1270           2 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BOOL_XOR);
    1271           2 :                         op2_val = zval_is_true(op2);
    1272             :                 }
    1273             :         } while (0);
    1274             : 
    1275           2 :         ZVAL_BOOL(result, op1_val ^ op2_val);
    1276           2 :         return SUCCESS;
    1277             : }
    1278             : /* }}} */
    1279             : 
    1280         343 : ZEND_API int ZEND_FASTCALL boolean_not_function(zval *result, zval *op1) /* {{{ */
    1281             : {
    1282         343 :         if (Z_TYPE_P(op1) < IS_TRUE) {
    1283           9 :                 ZVAL_TRUE(result);
    1284         334 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1285         296 :                 ZVAL_FALSE(result);
    1286             :         } else {
    1287          38 :                 if (Z_ISREF_P(op1)) {
    1288           0 :                         op1 = Z_REFVAL_P(op1);
    1289           0 :                         if (Z_TYPE_P(op1) < IS_TRUE) {
    1290           0 :                                 ZVAL_TRUE(result);
    1291           0 :                                 return SUCCESS;
    1292           0 :                         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1293           0 :                                 ZVAL_FALSE(result);
    1294           0 :                                 return SUCCESS;
    1295             :                         }
    1296             :                 }
    1297          38 :                 ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
    1298             : 
    1299          38 :                 ZVAL_BOOL(result, !zval_is_true(op1));
    1300             :         }
    1301         343 :         return SUCCESS;
    1302             : }
    1303             : /* }}} */
    1304             : 
    1305         118 : ZEND_API int ZEND_FASTCALL bitwise_not_function(zval *result, zval *op1) /* {{{ */
    1306             : {
    1307             : try_again:
    1308         118 :         switch (Z_TYPE_P(op1)) {
    1309             :                 case IS_LONG:
    1310          97 :                         ZVAL_LONG(result, ~Z_LVAL_P(op1));
    1311          97 :                         return SUCCESS;
    1312             :                 case IS_DOUBLE:
    1313           6 :                         ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
    1314           3 :                         return SUCCESS;
    1315             :                 case IS_STRING: {
    1316             :                         size_t i;
    1317             : 
    1318          15 :                         if (Z_STRLEN_P(op1) == 1) {
    1319           1 :                                 zend_uchar not = (zend_uchar) ~*Z_STRVAL_P(op1);
    1320           1 :                                 if (CG(one_char_string)[not]) {
    1321           0 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[not]);
    1322             :                                 } else {
    1323           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &not, 1, 0));
    1324             :                                 }
    1325             :                         } else {
    1326          28 :                                 ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0));
    1327          81 :                                 for (i = 0; i < Z_STRLEN_P(op1); i++) {
    1328          67 :                                         Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
    1329             :                                 }
    1330          14 :                                 Z_STRVAL_P(result)[i] = 0;
    1331             :                         }
    1332          15 :                         return SUCCESS;
    1333             :                 }
    1334             :                 case IS_REFERENCE:
    1335           0 :                         op1 = Z_REFVAL_P(op1);
    1336           0 :                         goto try_again;
    1337             :                 default:
    1338           3 :                         ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
    1339             : 
    1340           2 :                         zend_throw_error(NULL, "Unsupported operand types");
    1341           2 :                         return FAILURE;
    1342             :         }
    1343             : }
    1344             : /* }}} */
    1345             : 
    1346      454475 : ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1347             : {
    1348             :         zend_long op1_lval, op2_lval;
    1349             : 
    1350      908718 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1351      454159 :                 ZVAL_LONG(result, Z_LVAL_P(op1) | Z_LVAL_P(op2));
    1352      454159 :                 return SUCCESS;
    1353             :         }
    1354             : 
    1355         316 :         ZVAL_DEREF(op1);
    1356         316 :         ZVAL_DEREF(op2);
    1357             : 
    1358         527 :         if (Z_TYPE_P(op1) == IS_STRING && EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1359             :                 zval *longer, *shorter;
    1360             :                 zend_string *str;
    1361             :                 size_t i;
    1362             : 
    1363         200 :                 if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
    1364         117 :                         if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
    1365           1 :                                 zend_uchar or = (zend_uchar) (*Z_STRVAL_P(op1) | *Z_STRVAL_P(op2));
    1366           1 :                                 if (CG(one_char_string)[or]) {
    1367           0 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[or]);
    1368             :                                 } else {
    1369           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &or, 1, 0));
    1370             :                                 }
    1371           1 :                                 return SUCCESS;
    1372             :                         }
    1373         116 :                         longer = op1;
    1374         116 :                         shorter = op2;
    1375             :                 } else {
    1376          83 :                         longer = op2;
    1377          83 :                         shorter = op1;
    1378             :                 }
    1379             : 
    1380         398 :                 str = zend_string_alloc(Z_STRLEN_P(longer), 0);
    1381         886 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1382         687 :                         ZSTR_VAL(str)[i] = Z_STRVAL_P(longer)[i] | Z_STRVAL_P(shorter)[i];
    1383             :                 }
    1384         199 :                 memcpy(ZSTR_VAL(str) + i, Z_STRVAL_P(longer) + i, Z_STRLEN_P(longer) - i + 1);
    1385         199 :                 if (result==op1) {
    1386           1 :                         zend_string_release(Z_STR_P(result));
    1387             :                 }
    1388         199 :                 ZVAL_NEW_STR(result, str);
    1389         199 :                 return SUCCESS;
    1390             :         }
    1391             : 
    1392         116 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1393          64 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
    1394          30 :                 op1_lval = _zval_get_long_func_noisy(op1);
    1395             :         } else {
    1396          84 :                 op1_lval = Z_LVAL_P(op1);
    1397             :         }
    1398         114 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1399          24 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
    1400          23 :                 op2_lval = _zval_get_long_func_noisy(op2);
    1401             :         } else {
    1402          90 :                 op2_lval = Z_LVAL_P(op2);
    1403             :         }
    1404             : 
    1405         113 :         if (op1 == result) {
    1406             :                 zval_dtor(result);
    1407             :         }
    1408         113 :         ZVAL_LONG(result, op1_lval | op2_lval);
    1409         113 :         return SUCCESS;
    1410             : }
    1411             : /* }}} */
    1412             : 
    1413     6042585 : ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1414             : {
    1415             :         zend_long op1_lval, op2_lval;
    1416             : 
    1417    12084931 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1418     6042322 :                 ZVAL_LONG(result, Z_LVAL_P(op1) & Z_LVAL_P(op2));
    1419     6042322 :                 return SUCCESS;
    1420             :         }
    1421             : 
    1422         263 :         ZVAL_DEREF(op1);
    1423         263 :         ZVAL_DEREF(op2);
    1424             : 
    1425         471 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1426             :                 zval *longer, *shorter;
    1427             :                 zend_string *str;
    1428             :                 size_t i;
    1429             : 
    1430         201 :                 if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
    1431         117 :                         if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
    1432           1 :                                 zend_uchar and = (zend_uchar) (*Z_STRVAL_P(op1) & *Z_STRVAL_P(op2));
    1433           1 :                                 if (CG(one_char_string)[and]) {
    1434           0 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[and]);
    1435             :                                 } else {
    1436           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &and, 1, 0));
    1437             :                                 }
    1438           1 :                                 return SUCCESS;
    1439             :                         }
    1440         116 :                         longer = op1;
    1441         116 :                         shorter = op2;
    1442             :                 } else {
    1443          84 :                         longer = op2;
    1444          84 :                         shorter = op1;
    1445             :                 }
    1446             : 
    1447         400 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1448         886 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1449         686 :                         ZSTR_VAL(str)[i] = Z_STRVAL_P(shorter)[i] & Z_STRVAL_P(longer)[i];
    1450             :                 }
    1451         200 :                 ZSTR_VAL(str)[i] = 0;
    1452         200 :                 if (result==op1) {
    1453           1 :                         zend_string_release(Z_STR_P(result));
    1454             :                 }
    1455         200 :                 ZVAL_NEW_STR(result, str);
    1456         200 :                 return SUCCESS;
    1457             :         }
    1458             : 
    1459          62 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1460          76 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
    1461          36 :                 op1_lval = _zval_get_long_func_noisy(op1);
    1462             :         } else {
    1463          24 :                 op1_lval = Z_LVAL_P(op1);
    1464             :         }
    1465          60 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1466          29 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
    1467          28 :                 op2_lval = _zval_get_long_func_noisy(op2);
    1468             :         } else {
    1469          31 :                 op2_lval = Z_LVAL_P(op2);
    1470             :         }
    1471             : 
    1472          59 :         if (op1 == result) {
    1473             :                 zval_dtor(result);
    1474             :         }
    1475          59 :         ZVAL_LONG(result, op1_lval & op2_lval);
    1476          59 :         return SUCCESS;
    1477             : }
    1478             : /* }}} */
    1479             : 
    1480        2547 : ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1481             : {
    1482             :         zend_long op1_lval, op2_lval;
    1483             : 
    1484        4861 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1485        2291 :                 ZVAL_LONG(result, Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
    1486        2291 :                 return SUCCESS;
    1487             :         }
    1488             : 
    1489         256 :         ZVAL_DEREF(op1);
    1490         256 :         ZVAL_DEREF(op2);
    1491             : 
    1492         465 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1493             :                 zval *longer, *shorter;
    1494             :                 zend_string *str;
    1495             :                 size_t i;
    1496             : 
    1497         202 :                 if (EXPECTED(Z_STRLEN_P(op1) >= Z_STRLEN_P(op2))) {
    1498         118 :                         if (EXPECTED(Z_STRLEN_P(op1) == Z_STRLEN_P(op2)) && Z_STRLEN_P(op1) == 1) {
    1499           1 :                                 zend_uchar xor = (zend_uchar) (*Z_STRVAL_P(op1) ^ *Z_STRVAL_P(op2));
    1500           1 :                                 if (CG(one_char_string)[xor]) {
    1501           0 :                                         ZVAL_INTERNED_STR(result, CG(one_char_string)[xor]);
    1502             :                                 } else {
    1503           2 :                                         ZVAL_NEW_STR(result, zend_string_init((char *) &xor, 1, 0));
    1504             :                                 }
    1505           1 :                                 return SUCCESS;
    1506             :                         }
    1507         117 :                         longer = op1;
    1508         117 :                         shorter = op2;
    1509             :                 } else {
    1510          84 :                         longer = op2;
    1511          84 :                         shorter = op1;
    1512             :                 }
    1513             : 
    1514         402 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1515         890 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1516         689 :                         ZSTR_VAL(str)[i] = Z_STRVAL_P(shorter)[i] ^ Z_STRVAL_P(longer)[i];
    1517             :                 }
    1518         201 :                 ZSTR_VAL(str)[i] = 0;
    1519         201 :                 if (result==op1) {
    1520           1 :                         zend_string_release(Z_STR_P(result));
    1521             :                 }
    1522         201 :                 ZVAL_NEW_STR(result, str);
    1523         201 :                 return SUCCESS;
    1524             :         }
    1525             : 
    1526          54 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1527          62 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
    1528          29 :                 op1_lval = _zval_get_long_func_noisy(op1);
    1529             :         } else {
    1530          23 :                 op1_lval = Z_LVAL_P(op1);
    1531             :         }
    1532          52 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1533          27 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
    1534          26 :                 op2_lval = _zval_get_long_func_noisy(op2);
    1535             :         } else {
    1536          25 :                 op2_lval = Z_LVAL_P(op2);
    1537             :         }
    1538             : 
    1539          51 :         if (op1 == result) {
    1540             :                 zval_dtor(result);
    1541             :         }
    1542          51 :         ZVAL_LONG(result, op1_lval ^ op2_lval);
    1543          51 :         return SUCCESS;
    1544             : }
    1545             : /* }}} */
    1546             : 
    1547        4629 : ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1548             : {
    1549             :         zend_long op1_lval, op2_lval;
    1550             : 
    1551       12392 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function);
    1552             : 
    1553        3624 :         if (op1 == result) {
    1554             :                 zval_dtor(result);
    1555             :         }
    1556             : 
    1557             :         /* prevent wrapping quirkiness on some processors where << 64 + x == << x */
    1558        3624 :         if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
    1559         338 :                 if (EXPECTED(op2_lval > 0)) {
    1560         216 :                         ZVAL_LONG(result, 0);
    1561         216 :                         return SUCCESS;
    1562             :                 } else {
    1563         244 :                         if (EG(current_execute_data) && !CG(in_compilation)) {
    1564         122 :                                 zend_throw_exception_ex(zend_ce_arithmetic_error, 0, "Bit shift by negative number");
    1565             :                         } else {
    1566           0 :                                 zend_error_noreturn(E_ERROR, "Bit shift by negative number");
    1567             :                         }
    1568         122 :                         ZVAL_UNDEF(result);
    1569         122 :                         return FAILURE;
    1570             :                 }
    1571             :         }
    1572             : 
    1573        3286 :         ZVAL_LONG(result, op1_lval << op2_lval);
    1574        3286 :         return SUCCESS;
    1575             : }
    1576             : /* }}} */
    1577             : 
    1578     4139300 : ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1579             : {
    1580             :         zend_long op1_lval, op2_lval;
    1581             : 
    1582     8279730 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function);
    1583             : 
    1584     4139297 :         if (op1 == result) {
    1585             :                 zval_dtor(result);
    1586             :         }
    1587             : 
    1588             :         /* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
    1589     4139297 :         if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
    1590         338 :                 if (EXPECTED(op2_lval > 0)) {
    1591         216 :                         ZVAL_LONG(result, (op1_lval < 0) ? -1 : 0);
    1592         216 :                         return SUCCESS;
    1593             :                 } else {
    1594         244 :                         if (EG(current_execute_data) && !CG(in_compilation)) {
    1595         122 :                                 zend_throw_exception_ex(zend_ce_arithmetic_error, 0, "Bit shift by negative number");
    1596             :                         } else {
    1597           0 :                                 zend_error_noreturn(E_ERROR, "Bit shift by negative number");
    1598             :                         }
    1599         122 :                         ZVAL_UNDEF(result);
    1600         122 :                         return FAILURE;
    1601             :                 }
    1602             :         }
    1603             : 
    1604     4138959 :         ZVAL_LONG(result, op1_lval >> op2_lval);
    1605     4138959 :         return SUCCESS;
    1606             : }
    1607             : /* }}} */
    1608             : 
    1609     8106105 : ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1610             : {
    1611             :         zval op1_copy, op2_copy;
    1612     8106105 :         int use_copy1 = 0, use_copy2 = 0;
    1613             : 
    1614             :         do {
    1615     8106105 :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) {
    1616       50640 :                         if (Z_ISREF_P(op1)) {
    1617       19047 :                                 op1 = Z_REFVAL_P(op1);
    1618       19047 :                                 if (Z_TYPE_P(op1) == IS_STRING) break;
    1619             :                         }
    1620       94789 :                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
    1621       31600 :                         use_copy1 = zend_make_printable_zval(op1, &op1_copy);
    1622       31600 :                         if (use_copy1) {
    1623             :                                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1624             :                                  * we have to free it.
    1625             :                                  */
    1626       31600 :                                 if (result == op1) {
    1627             :                                         zval_dtor(op1);
    1628           9 :                                         if (UNEXPECTED(op1 == op2)) {
    1629           0 :                                                 op2 = &op1_copy;
    1630             :                                         }
    1631             :                                 }
    1632       31600 :                                 op1 = &op1_copy;
    1633             :                         }
    1634             :                 }
    1635             :         } while (0);
    1636             :         do {
    1637     8106105 :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) {
    1638     1478192 :                         if (Z_ISREF_P(op2)) {
    1639        1628 :                                 op2 = Z_REFVAL_P(op2);
    1640        1628 :                                 if (Z_TYPE_P(op2) == IS_STRING) break;
    1641             :                         }
    1642     1478082 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT);
    1643     1478082 :                         use_copy2 = zend_make_printable_zval(op2, &op2_copy);
    1644     1478082 :                         if (use_copy2) {
    1645     1478082 :                                 op2 = &op2_copy;
    1646             :                         }
    1647             :                 }
    1648             :         } while (0);
    1649             : 
    1650             :         {
    1651     8106105 :                 size_t op1_len = Z_STRLEN_P(op1);
    1652     8106105 :                 size_t op2_len = Z_STRLEN_P(op2);
    1653     8106105 :                 size_t result_len = op1_len + op2_len;
    1654             :                 zend_string *result_str;
    1655             : 
    1656     8106105 :                 if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) {
    1657           0 :                         zend_throw_error(NULL, "String size overflow");
    1658           0 :                         ZVAL_FALSE(result);
    1659           0 :                         return FAILURE;
    1660             :                 }
    1661             : 
    1662    15006538 :                 if (result == op1 && Z_REFCOUNTED_P(result)) {
    1663             :                         /* special case, perform operations on result */
    1664    13800866 :                         result_str = zend_string_extend(Z_STR_P(result), result_len, 0);
    1665             :                 } else {
    1666     1205672 :                         result_str = zend_string_alloc(result_len, 0);
    1667     1205672 :                         memcpy(ZSTR_VAL(result_str), Z_STRVAL_P(op1), op1_len);
    1668             :                 }
    1669             : 
    1670             :                 /* This has to happen first to account for the cases where result == op1 == op2 and
    1671             :                  * the realloc is done. In this case this line will also update Z_STRVAL_P(op2) to
    1672             :                  * point to the new string. The first op2_len bytes of result will still be the same. */
    1673     8106105 :                 ZVAL_NEW_STR(result, result_str);
    1674             : 
    1675     8106105 :                 memcpy(ZSTR_VAL(result_str) + op1_len, Z_STRVAL_P(op2), op2_len);
    1676     8106105 :                 ZSTR_VAL(result_str)[result_len] = '\0';
    1677             :         }
    1678             : 
    1679     8106105 :         if (UNEXPECTED(use_copy1)) {
    1680             :                 zval_dtor(op1);
    1681             :         }
    1682     8106105 :         if (UNEXPECTED(use_copy2)) {
    1683             :                 zval_dtor(op2);
    1684             :         }
    1685     8106105 :         return SUCCESS;
    1686             : }
    1687             : /* }}} */
    1688             : 
    1689           0 : ZEND_API int ZEND_FASTCALL string_compare_function_ex(zval *op1, zval *op2, zend_bool case_insensitive) /* {{{ */
    1690             : {
    1691           0 :         zend_string *str1 = zval_get_string(op1);
    1692           0 :         zend_string *str2 = zval_get_string(op2);
    1693             :         int ret;
    1694             : 
    1695           0 :         if (case_insensitive) {
    1696           0 :                 ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1));
    1697             :         } else {
    1698           0 :                 ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2));
    1699             :         }
    1700             : 
    1701             :         zend_string_release(str1);
    1702             :         zend_string_release(str2);
    1703           0 :         return ret;
    1704             : }
    1705             : /* }}} */
    1706             : 
    1707      238750 : ZEND_API int ZEND_FASTCALL string_compare_function(zval *op1, zval *op2) /* {{{ */
    1708             : {
    1709      471396 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1710      232646 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1711      230439 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1712         228 :                         return 0;
    1713             :                 } else {
    1714      230211 :                         return zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1715             :                 }
    1716             :         } else {
    1717        8311 :                 zend_string *str1 = zval_get_string(op1);
    1718        8311 :                 zend_string *str2 = zval_get_string(op2);
    1719        8311 :                 int ret = zend_binary_strcmp(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str2));
    1720             : 
    1721             :                 zend_string_release(str1);
    1722             :                 zend_string_release(str2);
    1723        8311 :                 return ret;
    1724             :         }
    1725             : }
    1726             : /* }}} */
    1727             : 
    1728          99 : ZEND_API int ZEND_FASTCALL string_case_compare_function(zval *op1, zval *op2) /* {{{ */
    1729             : {
    1730         185 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1731          86 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1732          86 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1733           0 :                         return 0;
    1734             :                 } else {
    1735          86 :                         return zend_binary_strcasecmp_l(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1736             :                 }
    1737             :         } else {
    1738          13 :                 zend_string *str1 = zval_get_string(op1);
    1739          13 :                 zend_string *str2 = zval_get_string(op2);
    1740          13 :                 int ret = zend_binary_strcasecmp_l(ZSTR_VAL(str1), ZSTR_LEN(str1), ZSTR_VAL(str2), ZSTR_LEN(str1));
    1741             : 
    1742             :                 zend_string_release(str1);
    1743             :                 zend_string_release(str2);
    1744          13 :                 return ret;
    1745             :         }
    1746             : }
    1747             : /* }}} */
    1748             : 
    1749             : #if HAVE_STRCOLL
    1750          29 : ZEND_API int ZEND_FASTCALL string_locale_compare_function(zval *op1, zval *op2) /* {{{ */
    1751             : {
    1752          29 :         zend_string *str1 = zval_get_string(op1);
    1753          29 :         zend_string *str2 = zval_get_string(op2);
    1754          29 :         int ret = strcoll(ZSTR_VAL(str1), ZSTR_VAL(str2));
    1755             : 
    1756             :         zend_string_release(str1);
    1757             :         zend_string_release(str2);
    1758          29 :         return ret;
    1759             : }
    1760             : /* }}} */
    1761             : #endif
    1762             : 
    1763         565 : ZEND_API int ZEND_FASTCALL numeric_compare_function(zval *op1, zval *op2) /* {{{ */
    1764             : {
    1765             :         double d1, d2;
    1766             : 
    1767         565 :         d1 = zval_get_double(op1);
    1768         565 :         d2 = zval_get_double(op2);
    1769             : 
    1770         565 :         return ZEND_NORMALIZE_BOOL(d1 - d2);
    1771             : }
    1772             : /* }}} */
    1773             : 
    1774         415 : static inline void zend_free_obj_get_result(zval *op) /* {{{ */
    1775             : {
    1776         415 :         if (Z_REFCOUNTED_P(op)) {
    1777           1 :                 if (Z_REFCOUNT_P(op) == 0) {
    1778             :                         zval_dtor(op);
    1779             :                 } else {
    1780           1 :                         zval_ptr_dtor(op);
    1781             :                 }
    1782             :         }
    1783         415 : }
    1784             : /* }}} */
    1785             : 
    1786           0 : static void ZEND_FASTCALL convert_compare_result_to_long(zval *result) /* {{{ */
    1787             : {
    1788           0 :         if (Z_TYPE_P(result) == IS_DOUBLE) {
    1789           0 :                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1790             :         } else {
    1791           0 :                 convert_to_long(result);
    1792             :         }
    1793           0 : }
    1794             : /* }}} */
    1795             : 
    1796      836231 : ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1797             : {
    1798             :         int ret;
    1799      836231 :         int converted = 0;
    1800             :         zval op1_copy, op2_copy;
    1801             :         zval *op_free, tmp_free;
    1802             : 
    1803             :         while (1) {
    1804     2029606 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1805             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1806       65085 :                                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1807       65085 :                                 return SUCCESS;
    1808             : 
    1809             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1810         421 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
    1811         421 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1812         421 :                                 return SUCCESS;
    1813             : 
    1814             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1815         342 :                                 Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
    1816         342 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1817         342 :                                 return SUCCESS;
    1818             : 
    1819             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1820         371 :                                 if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
    1821          95 :                                         ZVAL_LONG(result, 0);
    1822             :                                 } else {
    1823         276 :                                         Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    1824         276 :                                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1825             :                                 }
    1826         371 :                                 return SUCCESS;
    1827             : 
    1828             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
    1829         552 :                                 ZVAL_LONG(result, zend_compare_arrays(op1, op2));
    1830         552 :                                 return SUCCESS;
    1831             : 
    1832             :                         case TYPE_PAIR(IS_NULL, IS_NULL):
    1833             :                         case TYPE_PAIR(IS_NULL, IS_FALSE):
    1834             :                         case TYPE_PAIR(IS_FALSE, IS_NULL):
    1835             :                         case TYPE_PAIR(IS_FALSE, IS_FALSE):
    1836             :                         case TYPE_PAIR(IS_TRUE, IS_TRUE):
    1837        3218 :                                 ZVAL_LONG(result, 0);
    1838        3218 :                                 return SUCCESS;
    1839             : 
    1840             :                         case TYPE_PAIR(IS_NULL, IS_TRUE):
    1841          13 :                                 ZVAL_LONG(result, -1);
    1842          13 :                                 return SUCCESS;
    1843             : 
    1844             :                         case TYPE_PAIR(IS_TRUE, IS_NULL):
    1845          12 :                                 ZVAL_LONG(result, 1);
    1846          12 :                                 return SUCCESS;
    1847             : 
    1848             :                         case TYPE_PAIR(IS_STRING, IS_STRING):
    1849      351968 :                                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1850         225 :                                         ZVAL_LONG(result, 0);
    1851         225 :                                         return SUCCESS;
    1852             :                                 }
    1853      351743 :                                 ZVAL_LONG(result, zendi_smart_strcmp(Z_STR_P(op1), Z_STR_P(op2)));
    1854      351743 :                                 return SUCCESS;
    1855             : 
    1856             :                         case TYPE_PAIR(IS_NULL, IS_STRING):
    1857       13191 :                                 ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
    1858       13191 :                                 return SUCCESS;
    1859             : 
    1860             :                         case TYPE_PAIR(IS_STRING, IS_NULL):
    1861         115 :                                 ZVAL_LONG(result, Z_STRLEN_P(op1) == 0 ? 0 : 1);
    1862         115 :                                 return SUCCESS;
    1863             : 
    1864             :                         case TYPE_PAIR(IS_OBJECT, IS_NULL):
    1865          49 :                                 ZVAL_LONG(result, 1);
    1866          49 :                                 return SUCCESS;
    1867             : 
    1868             :                         case TYPE_PAIR(IS_NULL, IS_OBJECT):
    1869          15 :                                 ZVAL_LONG(result, -1);
    1870          15 :                                 return SUCCESS;
    1871             : 
    1872             :                         default:
    1873      579451 :                                 if (Z_ISREF_P(op1)) {
    1874      122553 :                                         op1 = Z_REFVAL_P(op1);
    1875      122553 :                                         continue;
    1876      456898 :                                 } else if (Z_ISREF_P(op2)) {
    1877       27188 :                                         op2 = Z_REFVAL_P(op2);
    1878       27188 :                                         continue;
    1879             :                                 }
    1880             : 
    1881      429710 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
    1882       25018 :                                         ret = Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2);
    1883       25018 :                                         if (UNEXPECTED(Z_TYPE_P(result) != IS_LONG)) {
    1884           0 :                                                 convert_compare_result_to_long(result);
    1885             :                                         }
    1886       25018 :                                         return ret;
    1887      404692 :                                 } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
    1888       25004 :                                         ret = Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2);
    1889       25004 :                                         if (UNEXPECTED(Z_TYPE_P(result) != IS_LONG)) {
    1890           0 :                                                 convert_compare_result_to_long(result);
    1891             :                                         }
    1892       25004 :                                         return ret;
    1893             :                                 }
    1894             : 
    1895      726123 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
    1896      346220 :                                         if (Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
    1897             :                                                 /* object handles are identical, apparently this is the same object */
    1898          25 :                                                 ZVAL_LONG(result, 0);
    1899          25 :                                                 return SUCCESS;
    1900             :                                         }
    1901      346195 :                                         if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
    1902      346194 :                                                 ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2));
    1903      346190 :                                                 return SUCCESS;
    1904             :                                         }
    1905             :                                 }
    1906       33469 :                                 if (Z_TYPE_P(op1) == IS_OBJECT) {
    1907         216 :                                         if (Z_OBJ_HT_P(op1)->get) {
    1908             :                                                 zval rv;
    1909           1 :                                                 op_free = Z_OBJ_HT_P(op1)->get(op1, &rv);
    1910           1 :                                                 ret = compare_function(result, op_free, op2);
    1911           1 :                                                 zend_free_obj_get_result(op_free);
    1912           1 :                                                 return ret;
    1913         215 :                                         } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
    1914         214 :                                                 ZVAL_UNDEF(&tmp_free);
    1915         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) {
    1916         111 :                                                         ZVAL_LONG(result, 1);
    1917         111 :                                                         zend_free_obj_get_result(&tmp_free);
    1918         111 :                                                         return SUCCESS;
    1919             :                                                 }
    1920         103 :                                                 ret = compare_function(result, &tmp_free, op2);
    1921         103 :                                                 zend_free_obj_get_result(&tmp_free);
    1922         103 :                                                 return ret;
    1923             :                                         }
    1924             :                                 }
    1925       33254 :                                 if (Z_TYPE_P(op2) == IS_OBJECT) {
    1926         201 :                                         if (Z_OBJ_HT_P(op2)->get) {
    1927             :                                                 zval rv;
    1928           0 :                                                 op_free = Z_OBJ_HT_P(op2)->get(op2, &rv);
    1929           0 :                                                 ret = compare_function(result, op1, op_free);
    1930           0 :                                                 zend_free_obj_get_result(op_free);
    1931           0 :                                                 return ret;
    1932         201 :                                         } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
    1933         200 :                                                 ZVAL_UNDEF(&tmp_free);
    1934         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) {
    1935         107 :                                                         ZVAL_LONG(result, -1);
    1936         107 :                                                         zend_free_obj_get_result(&tmp_free);
    1937         107 :                                                         return SUCCESS;
    1938             :                                                 }
    1939          93 :                                                 ret = compare_function(result, op1, &tmp_free);
    1940          93 :                                                 zend_free_obj_get_result(&tmp_free);
    1941          93 :                                                 return ret;
    1942           1 :                                         } else if (Z_TYPE_P(op1) == IS_OBJECT) {
    1943           1 :                                                 ZVAL_LONG(result, 1);
    1944           1 :                                                 return SUCCESS;
    1945             :                                         }
    1946             :                                 }
    1947       33053 :                                 if (!converted) {
    1948       64837 :                                         if (Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op1) == IS_FALSE) {
    1949        2144 :                                                 ZVAL_LONG(result, zval_is_true(op2) ? -1 : 0);
    1950        2144 :                                                 return SUCCESS;
    1951       60650 :                                         } else if (Z_TYPE_P(op2) == IS_NULL || Z_TYPE_P(op2) == IS_FALSE) {
    1952        1174 :                                                 ZVAL_LONG(result, zval_is_true(op1) ? 1 : 0);
    1953        1174 :                                                 return SUCCESS;
    1954       29195 :                                         } else if (Z_TYPE_P(op1) == IS_TRUE) {
    1955         182 :                                                 ZVAL_LONG(result, zval_is_true(op2) ? 0 : 1);
    1956         182 :                                                 return SUCCESS;
    1957       29013 :                                         } else if (Z_TYPE_P(op2) == IS_TRUE) {
    1958         182 :                                                 ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
    1959         182 :                                                 return SUCCESS;
    1960             :                                         } else {
    1961       72404 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result, 1);
    1962       71471 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result, 1);
    1963       28831 :                                                 converted = 1;
    1964             :                                         }
    1965         540 :                                 } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    1966         281 :                                         ZVAL_LONG(result, 1);
    1967         281 :                                         return SUCCESS;
    1968         259 :                                 } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    1969         259 :                                         ZVAL_LONG(result, -1);
    1970         259 :                                         return SUCCESS;
    1971           0 :                                 } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    1972           0 :                                         ZVAL_LONG(result, 1);
    1973           0 :                                         return SUCCESS;
    1974           0 :                                 } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    1975           0 :                                         ZVAL_LONG(result, -1);
    1976           0 :                                         return SUCCESS;
    1977             :                                 } else {
    1978           0 :                                         ZVAL_LONG(result, 0);
    1979           0 :                                         return FAILURE;
    1980             :                                 }
    1981             :                 }
    1982      178572 :         }
    1983             : }
    1984             : /* }}} */
    1985             : 
    1986        1144 : static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */
    1987             : {
    1988             :         zval result;
    1989             : 
    1990             :         /* is_identical_function() returns 1 in case of identity and 0 in case
    1991             :          * of a difference;
    1992             :          * whereas this comparison function is expected to return 0 on identity,
    1993             :          * and non zero otherwise.
    1994             :          */
    1995        1144 :         ZVAL_DEREF(z1);
    1996        1144 :         ZVAL_DEREF(z2);
    1997        1144 :         if (is_identical_function(&result, z1, z2)==FAILURE) {
    1998           0 :                 return 1;
    1999             :         }
    2000        1144 :         return Z_TYPE(result) != IS_TRUE;
    2001             : }
    2002             : /* }}} */
    2003             : 
    2004      987670 : ZEND_API int ZEND_FASTCALL zend_is_identical(zval *op1, zval *op2) /* {{{ */
    2005             : {
    2006      987670 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    2007           0 :                 return 0;
    2008             :         }
    2009      987670 :         switch (Z_TYPE_P(op1)) {
    2010             :                 case IS_NULL:
    2011             :                 case IS_FALSE:
    2012             :                 case IS_TRUE:
    2013           3 :                         return 1;
    2014             :                 case IS_LONG:
    2015      878775 :                         return (Z_LVAL_P(op1) == Z_LVAL_P(op2));
    2016             :                 case IS_RESOURCE:
    2017          13 :                         return (Z_RES_P(op1) == Z_RES_P(op2));
    2018             :                 case IS_DOUBLE:
    2019         180 :                         return (Z_DVAL_P(op1) == Z_DVAL_P(op2));
    2020             :                 case IS_STRING:
    2021       78068 :                         return (Z_STR_P(op1) == Z_STR_P(op2) ||
    2022       19548 :                                 (Z_STRLEN_P(op1) == Z_STRLEN_P(op2) &&
    2023       15980 :                                  memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0));
    2024             :                 case IS_ARRAY:
    2025         141 :                         return (Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
    2026          69 :                                 zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1) == 0);
    2027             :                 case IS_OBJECT:
    2028       66087 :                         return (Z_OBJ_P(op1) == Z_OBJ_P(op2) && Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2));
    2029             :                 default:
    2030           0 :                         return 0;
    2031             :         }
    2032             : }
    2033             : /* }}} */
    2034             : 
    2035        1148 : ZEND_API int ZEND_FASTCALL is_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2036             : {
    2037        1148 :         ZVAL_BOOL(result, zend_is_identical(op1, op2));
    2038        1148 :         return SUCCESS;
    2039             : }
    2040             : /* }}} */
    2041             : 
    2042          19 : ZEND_API int ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2043             : {
    2044          19 :         ZVAL_BOOL(result, !zend_is_identical(op1, op2));
    2045          19 :         return SUCCESS;
    2046             : }
    2047             : /* }}} */
    2048             : 
    2049          80 : ZEND_API int ZEND_FASTCALL is_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2050             : {
    2051          80 :         if (compare_function(result, op1, op2) == FAILURE) {
    2052           0 :                 return FAILURE;
    2053             :         }
    2054          80 :         ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
    2055          80 :         return SUCCESS;
    2056             : }
    2057             : /* }}} */
    2058             : 
    2059         414 : ZEND_API int ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2060             : {
    2061         414 :         if (compare_function(result, op1, op2) == FAILURE) {
    2062           0 :                 return FAILURE;
    2063             :         }
    2064         414 :         ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
    2065         414 :         return SUCCESS;
    2066             : }
    2067             : /* }}} */
    2068             : 
    2069        1955 : ZEND_API int ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2070             : {
    2071        1955 :         if (compare_function(result, op1, op2) == FAILURE) {
    2072           0 :                 return FAILURE;
    2073             :         }
    2074        1955 :         ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
    2075        1955 :         return SUCCESS;
    2076             : }
    2077             : /* }}} */
    2078             : 
    2079        1290 : ZEND_API int ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    2080             : {
    2081        1290 :         if (compare_function(result, op1, op2) == FAILURE) {
    2082           0 :                 return FAILURE;
    2083             :         }
    2084        1290 :         ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
    2085        1290 :         return SUCCESS;
    2086             : }
    2087             : /* }}} */
    2088             : 
    2089           0 : static zend_bool ZEND_FASTCALL instanceof_interface_only(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2090             : {
    2091             :         uint32_t i;
    2092             : 
    2093           0 :         for (i = 0; i < instance_ce->num_interfaces; i++) {
    2094           0 :                 if (instanceof_interface_only(instance_ce->interfaces[i], ce)) {
    2095           0 :                         return 1;
    2096             :                 }
    2097             :         }
    2098           0 :         return 0;
    2099             : }
    2100             : /* }}} */
    2101             : 
    2102             : static zend_always_inline zend_bool instanceof_class(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2103             : {
    2104     4377907 :         while (instance_ce) {
    2105     3769337 :                 if (instance_ce == ce) {
    2106     1974483 :                         return 1;
    2107             :                 }
    2108     1794854 :                 instance_ce = instance_ce->parent;
    2109             :         }
    2110      608570 :         return 0;
    2111             : }
    2112             : /* }}} */
    2113             : 
    2114     1313357 : static zend_bool ZEND_FASTCALL instanceof_interface(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2115             : {
    2116             :         uint32_t i;
    2117             : 
    2118     1762624 :         for (i = 0; i < instance_ce->num_interfaces; i++) {
    2119      881452 :                 if (instanceof_interface(instance_ce->interfaces[i], ce)) {
    2120      432185 :                         return 1;
    2121             :                 }
    2122             :         }
    2123      881172 :         return instanceof_class(instance_ce, ce);
    2124             : }
    2125             : /* }}} */
    2126             : 
    2127       73300 : ZEND_API zend_bool ZEND_FASTCALL instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only) /* {{{ */
    2128             : {
    2129       73300 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    2130       73293 :                 if (!interfaces_only) {
    2131           0 :                         if (instanceof_interface_only(instance_ce, ce)) {
    2132           0 :                                 return 1;
    2133             :                         }
    2134             :                 } else {
    2135       73293 :                         return instanceof_interface(instance_ce, ce);
    2136             :                 }
    2137             :         }
    2138           7 :         if (!interfaces_only) {
    2139           7 :                 return instanceof_class(instance_ce, ce);
    2140             :         }
    2141           0 :         return 0;
    2142             : }
    2143             : /* }}} */
    2144             : 
    2145     2060486 : ZEND_API zend_bool ZEND_FASTCALL instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2146             : {
    2147     2060486 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    2148      358612 :                 return instanceof_interface(instance_ce, ce);
    2149             :         } else {
    2150     1701874 :                 return instanceof_class(instance_ce, ce);
    2151             :         }
    2152             : }
    2153             : /* }}} */
    2154             : 
    2155             : #define LOWER_CASE 1
    2156             : #define UPPER_CASE 2
    2157             : #define NUMERIC 3
    2158             : 
    2159      100063 : static void ZEND_FASTCALL increment_string(zval *str) /* {{{ */
    2160             : {
    2161      100063 :         int carry=0;
    2162      100063 :         size_t pos=Z_STRLEN_P(str)-1;
    2163             :         char *s;
    2164             :         zend_string *t;
    2165      100063 :         int last=0; /* Shut up the compiler warning */
    2166             :         int ch;
    2167             : 
    2168      100063 :         if (Z_STRLEN_P(str) == 0) {
    2169           0 :                 zend_string_release(Z_STR_P(str));
    2170           0 :                 if (CG(one_char_string)['1']) {
    2171           0 :                         ZVAL_INTERNED_STR(str, CG(one_char_string)['1']);
    2172             :                 } else {
    2173           0 :                         Z_STR_P(str) = zend_string_init("1", sizeof("1")-1, 0);
    2174           0 :                         Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2175             :                 }
    2176           0 :                 return;
    2177             :         }
    2178             : 
    2179      100063 :         if (!Z_REFCOUNTED_P(str)) {
    2180          16 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2181           8 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2182      100055 :         } else if (Z_REFCOUNT_P(str) > 1) {
    2183             :                 Z_DELREF_P(str);
    2184           0 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2185             :         } else {
    2186      100055 :                 zend_string_forget_hash_val(Z_STR_P(str));
    2187             :         }
    2188      100063 :         s = Z_STRVAL_P(str);
    2189             : 
    2190             :         do {
    2191      104071 :                 ch = s[pos];
    2192      208113 :                 if (ch >= 'a' && ch <= 'z') {
    2193      104042 :                         if (ch == 'z') {
    2194        4007 :                                 s[pos] = 'a';
    2195        4007 :                                 carry=1;
    2196             :                         } else {
    2197      100035 :                                 s[pos]++;
    2198      100035 :                                 carry=0;
    2199             :                         }
    2200      104042 :                         last=LOWER_CASE;
    2201          40 :                 } else if (ch >= 'A' && ch <= 'Z') {
    2202          11 :                         if (ch == 'Z') {
    2203           4 :                                 s[pos] = 'A';
    2204           4 :                                 carry=1;
    2205             :                         } else {
    2206           7 :                                 s[pos]++;
    2207           7 :                                 carry=0;
    2208             :                         }
    2209          11 :                         last=UPPER_CASE;
    2210          32 :                 } else if (ch >= '0' && ch <= '9') {
    2211          14 :                         if (ch == '9') {
    2212           6 :                                 s[pos] = '0';
    2213           6 :                                 carry=1;
    2214             :                         } else {
    2215           8 :                                 s[pos]++;
    2216           8 :                                 carry=0;
    2217             :                         }
    2218          14 :                         last = NUMERIC;
    2219             :                 } else {
    2220           4 :                         carry=0;
    2221           4 :                         break;
    2222             :                 }
    2223      104067 :                 if (carry == 0) {
    2224      100050 :                         break;
    2225             :                 }
    2226        4017 :         } while (pos-- > 0);
    2227             : 
    2228      100063 :         if (carry) {
    2229          18 :                 t = zend_string_alloc(Z_STRLEN_P(str)+1, 0);
    2230           9 :                 memcpy(ZSTR_VAL(t) + 1, Z_STRVAL_P(str), Z_STRLEN_P(str));
    2231           9 :                 ZSTR_VAL(t)[Z_STRLEN_P(str) + 1] = '\0';
    2232           9 :                 switch (last) {
    2233             :                         case NUMERIC:
    2234           2 :                                 ZSTR_VAL(t)[0] = '1';
    2235           2 :                                 break;
    2236             :                         case UPPER_CASE:
    2237           2 :                                 ZSTR_VAL(t)[0] = 'A';
    2238           2 :                                 break;
    2239             :                         case LOWER_CASE:
    2240           5 :                                 ZSTR_VAL(t)[0] = 'a';
    2241             :                                 break;
    2242             :                 }
    2243           9 :                 zend_string_free(Z_STR_P(str));
    2244           9 :                 ZVAL_NEW_STR(str, t);
    2245             :         }
    2246             : }
    2247             : /* }}} */
    2248             : 
    2249      118606 : ZEND_API int ZEND_FASTCALL increment_function(zval *op1) /* {{{ */
    2250             : {
    2251             : try_again:
    2252      118606 :         switch (Z_TYPE_P(op1)) {
    2253             :                 case IS_LONG:
    2254             :                         fast_long_increment_function(op1);
    2255       16889 :                         break;
    2256             :                 case IS_DOUBLE:
    2257           4 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
    2258           4 :                         break;
    2259             :                 case IS_NULL:
    2260          30 :                         ZVAL_LONG(op1, 1);
    2261          30 :                         break;
    2262             :                 case IS_STRING: {
    2263             :                                 zend_long lval;
    2264             :                                 double dval;
    2265             : 
    2266      203360 :                                 switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2267             :                                         case IS_LONG:
    2268        1611 :                                                 zend_string_release(Z_STR_P(op1));
    2269        1611 :                                                 if (lval == ZEND_LONG_MAX) {
    2270             :                                                         /* switch to double */
    2271           0 :                                                         double d = (double)lval;
    2272           0 :                                                         ZVAL_DOUBLE(op1, d+1);
    2273             :                                                 } else {
    2274        1611 :                                                         ZVAL_LONG(op1, lval+1);
    2275             :                                                 }
    2276        1611 :                                                 break;
    2277             :                                         case IS_DOUBLE:
    2278           6 :                                                 zend_string_release(Z_STR_P(op1));
    2279           6 :                                                 ZVAL_DOUBLE(op1, dval+1);
    2280           6 :                                                 break;
    2281             :                                         default:
    2282             :                                                 /* Perl style string increment */
    2283      100063 :                                                 increment_string(op1);
    2284             :                                                 break;
    2285             :                                 }
    2286             :                         }
    2287      101680 :                         break;
    2288             :                 case IS_OBJECT:
    2289           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2290           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2291             :                                 /* proxy object */
    2292             :                                 zval rv;
    2293             :                                 zval *val;
    2294             : 
    2295           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
    2296           0 :                                 Z_TRY_ADDREF_P(val);
    2297           0 :                                 increment_function(val);
    2298           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val);
    2299           0 :                                 zval_ptr_dtor(val);
    2300           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2301             :                                 zval op2;
    2302             :                                 int res;
    2303             : 
    2304           2 :                                 ZVAL_LONG(&op2, 1);
    2305           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, &op2);
    2306           2 :                                 zval_ptr_dtor(&op2);
    2307             : 
    2308           2 :                                 return res;
    2309             :                         }
    2310           1 :                         return FAILURE;
    2311             :                 case IS_REFERENCE:
    2312           0 :                         op1 = Z_REFVAL_P(op1);
    2313           0 :                         goto try_again;
    2314             :                 default:
    2315           0 :                         return FAILURE;
    2316             :         }
    2317      118603 :         return SUCCESS;
    2318             : }
    2319             : /* }}} */
    2320             : 
    2321      163835 : ZEND_API int ZEND_FASTCALL decrement_function(zval *op1) /* {{{ */
    2322             : {
    2323             :         zend_long lval;
    2324             :         double dval;
    2325             : 
    2326             : try_again:
    2327      163835 :         switch (Z_TYPE_P(op1)) {
    2328             :                 case IS_LONG:
    2329             :                         fast_long_decrement_function(op1);
    2330          28 :                         break;
    2331             :                 case IS_DOUBLE:
    2332      163766 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
    2333      163766 :                         break;
    2334             :                 case IS_STRING:         /* Like perl we only support string increment */
    2335          33 :                         if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
    2336           1 :                                 zend_string_release(Z_STR_P(op1));
    2337           1 :                                 ZVAL_LONG(op1, -1);
    2338           1 :                                 break;
    2339             :                         }
    2340          64 :                         switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2341             :                                 case IS_LONG:
    2342           8 :                                         zend_string_release(Z_STR_P(op1));
    2343           8 :                                         if (lval == ZEND_LONG_MIN) {
    2344           1 :                                                 double d = (double)lval;
    2345           1 :                                                 ZVAL_DOUBLE(op1, d-1);
    2346             :                                         } else {
    2347           7 :                                                 ZVAL_LONG(op1, lval-1);
    2348             :                                         }
    2349           8 :                                         break;
    2350             :                                 case IS_DOUBLE:
    2351           7 :                                         zend_string_release(Z_STR_P(op1));
    2352           7 :                                         ZVAL_DOUBLE(op1, dval - 1);
    2353             :                                         break;
    2354             :                         }
    2355          32 :                         break;
    2356             :                 case IS_OBJECT:
    2357           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2358           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2359             :                                 /* proxy object */
    2360             :                                 zval rv;
    2361             :                                 zval *val;
    2362             : 
    2363           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
    2364           0 :                                 Z_TRY_ADDREF_P(val);
    2365           0 :                                 decrement_function(val);
    2366           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val);
    2367           0 :                                 zval_ptr_dtor(val);
    2368           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2369             :                                 zval op2;
    2370             :                                 int res;
    2371             : 
    2372           2 :                                 ZVAL_LONG(&op2, 1);
    2373           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, &op2);
    2374           2 :                                 zval_ptr_dtor(&op2);
    2375             : 
    2376           2 :                                 return res;
    2377             :                         }
    2378           1 :                         return FAILURE;
    2379             :                 case IS_REFERENCE:
    2380           0 :                         op1 = Z_REFVAL_P(op1);
    2381           0 :                         goto try_again;
    2382             :                 default:
    2383           5 :                         return FAILURE;
    2384             :         }
    2385             : 
    2386      163827 :         return SUCCESS;
    2387             : }
    2388             : /* }}} */
    2389             : 
    2390      119574 : ZEND_API int ZEND_FASTCALL zend_is_true(zval *op) /* {{{ */
    2391             : {
    2392      119573 :         return i_zend_is_true(op);
    2393             : }
    2394             : /* }}} */
    2395             : 
    2396      162647 : ZEND_API int ZEND_FASTCALL zend_object_is_true(zval *op) /* {{{ */
    2397             : {
    2398      162647 :         if (Z_OBJ_HT_P(op)->cast_object) {
    2399             :                 zval tmp;
    2400      162647 :                 if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL) == SUCCESS) {
    2401      162646 :                         return Z_TYPE(tmp) == IS_TRUE;
    2402             :                 }
    2403           1 :                 zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", ZSTR_VAL(Z_OBJ_P(op)->ce->name));
    2404           0 :         } else if (Z_OBJ_HT_P(op)->get) {
    2405             :                 int result;
    2406             :                 zval rv;
    2407           0 :                 zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv);
    2408             : 
    2409           0 :                 if (Z_TYPE_P(tmp) != IS_OBJECT) {
    2410             :                         /* for safety - avoid loop */
    2411           0 :                         result = i_zend_is_true(tmp);
    2412           0 :                         zval_ptr_dtor(tmp);
    2413           0 :                         return result;
    2414             :                 }
    2415             :         }
    2416           0 :         return 1;
    2417             : }
    2418             : /* }}} */
    2419             : 
    2420             : #ifdef ZEND_USE_TOLOWER_L
    2421             : ZEND_API void zend_update_current_locale(void) /* {{{ */
    2422             : {
    2423             :         current_locale = _get_current_locale();
    2424             : }
    2425             : /* }}} */
    2426             : #endif
    2427             : 
    2428   157424367 : ZEND_API char* ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length) /* {{{ */
    2429             : {
    2430   157424367 :         register unsigned char *str = (unsigned char*)source;
    2431   157424367 :         register unsigned char *result = (unsigned char*)dest;
    2432   157424367 :         register unsigned char *end = str + length;
    2433             : 
    2434  2397139188 :         while (str < end) {
    2435  2082290454 :                 *result++ = zend_tolower_ascii(*str++);
    2436             :         }
    2437   157424367 :         *result = '\0';
    2438             : 
    2439   157424367 :         return dest;
    2440             : }
    2441             : /* }}} */
    2442             : 
    2443     5080836 : ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t length) /* {{{ */
    2444             : {
    2445     5080836 :         return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
    2446             : }
    2447             : /* }}} */
    2448             : 
    2449       71396 : ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length) /* {{{ */
    2450             : {
    2451       71396 :         register unsigned char *p = (unsigned char*)str;
    2452       71396 :         register unsigned char *end = p + length;
    2453             : 
    2454      638929 :         while (p < end) {
    2455      496137 :                 *p = zend_tolower_ascii(*p);
    2456      496137 :                 p++;
    2457             :         }
    2458       71396 : }
    2459             : /* }}} */
    2460             : 
    2461         286 : ZEND_API char* ZEND_FASTCALL zend_str_tolower_dup_ex(const char *source, size_t length) /* {{{ */
    2462             : {
    2463         286 :         register const unsigned char *p = (const unsigned char*)source;
    2464         286 :         register const unsigned char *end = p + length;
    2465             : 
    2466        4712 :         while (p < end) {
    2467        4150 :                 if (*p != zend_tolower_ascii(*p)) {
    2468          10 :                         char *res = (char*)emalloc(length + 1);
    2469             :                         register unsigned char *r;
    2470             : 
    2471          10 :                         if (p != (const unsigned char*)source) {
    2472           2 :                                 memcpy(res, source, p - (const unsigned char*)source);
    2473             :                         }
    2474          10 :                         r = (unsigned char*)p + (res - source);
    2475          93 :                         while (p < end) {
    2476          73 :                                 *r = zend_tolower_ascii(*p);
    2477          73 :                                 p++;
    2478          73 :                                 r++;
    2479             :                         }
    2480          10 :                         *r = '\0';
    2481          10 :                         return res;
    2482             :                 }
    2483        4140 :                 p++;
    2484             :         }
    2485         276 :         return NULL;
    2486             : }
    2487             : /* }}} */
    2488             : 
    2489      614860 : ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower(zend_string *str) /* {{{ */
    2490             : {
    2491      614860 :         register unsigned char *p = (unsigned char*)ZSTR_VAL(str);
    2492      614860 :         register unsigned char *end = p + ZSTR_LEN(str);
    2493             : 
    2494    36727587 :         while (p < end) {
    2495    35708014 :                 if (*p != zend_tolower_ascii(*p)) {
    2496      420294 :                         zend_string *res = zend_string_alloc(ZSTR_LEN(str), 0);
    2497             :                         register unsigned char *r;
    2498             : 
    2499      210147 :                         if (p != (unsigned char*)ZSTR_VAL(str)) {
    2500       46390 :                                 memcpy(ZSTR_VAL(res), ZSTR_VAL(str), p - (unsigned char*)ZSTR_VAL(str));
    2501             :                         }
    2502      210147 :                         r = p + (ZSTR_VAL(res) - ZSTR_VAL(str));
    2503     1171115 :                         while (p < end) {
    2504      750821 :                                 *r = zend_tolower_ascii(*p);
    2505      750821 :                                 p++;
    2506      750821 :                                 r++;
    2507             :                         }
    2508      210147 :                         *r = '\0';
    2509      210147 :                         return res;
    2510             :                 }
    2511    35497867 :                 p++;
    2512             :         }
    2513      404713 :         return zend_string_copy(str);
    2514             : }
    2515             : /* }}} */
    2516             : 
    2517      901685 : ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2518             : {
    2519             :         int retval;
    2520             : 
    2521      901685 :         if (s1 == s2) {
    2522         321 :                 return 0;
    2523             :         }
    2524      901364 :         retval = memcmp(s1, s2, MIN(len1, len2));
    2525      901364 :         if (!retval) {
    2526      236534 :                 return (int)(len1 - len2);
    2527             :         } else {
    2528      664830 :                 return retval;
    2529             :         }
    2530             : }
    2531             : /* }}} */
    2532             : 
    2533       16194 : ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2534             : {
    2535             :         int retval;
    2536             : 
    2537       16194 :         if (s1 == s2) {
    2538          44 :                 return 0;
    2539             :         }
    2540       16150 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    2541       16150 :         if (!retval) {
    2542       15874 :                 return (int)(MIN(length, len1) - MIN(length, len2));
    2543             :         } else {
    2544         276 :                 return retval;
    2545             :         }
    2546             : }
    2547             : /* }}} */
    2548             : 
    2549     1043194 : ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2550             : {
    2551             :         size_t len;
    2552             :         int c1, c2;
    2553             : 
    2554     1043194 :         if (s1 == s2) {
    2555          80 :                 return 0;
    2556             :         }
    2557             : 
    2558     1043114 :         len = MIN(len1, len2);
    2559     3563796 :         while (len--) {
    2560     2369753 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2561     2369753 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2562     2369753 :                 if (c1 != c2) {
    2563      892185 :                         return c1 - c2;
    2564             :                 }
    2565             :         }
    2566             : 
    2567      150929 :         return (int)(len1 - len2);
    2568             : }
    2569             : /* }}} */
    2570             : 
    2571       22684 : ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2572             : {
    2573             :         size_t len;
    2574             :         int c1, c2;
    2575             : 
    2576       22684 :         if (s1 == s2) {
    2577          45 :                 return 0;
    2578             :         }
    2579       22639 :         len = MIN(length, MIN(len1, len2));
    2580       53544 :         while (len--) {
    2581        8777 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2582        8777 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2583        8777 :                 if (c1 != c2) {
    2584         511 :                         return c1 - c2;
    2585             :                 }
    2586             :         }
    2587             : 
    2588       22128 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2589             : }
    2590             : /* }}} */
    2591             : 
    2592         123 : ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2593             : {
    2594             :         size_t len;
    2595             :         int c1, c2;
    2596             : 
    2597         123 :         if (s1 == s2) {
    2598           0 :                 return 0;
    2599             :         }
    2600             : 
    2601         123 :         len = MIN(len1, len2);
    2602         560 :         while (len--) {
    2603         400 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2604         400 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2605         400 :                 if (c1 != c2) {
    2606          86 :                         return c1 - c2;
    2607             :                 }
    2608             :         }
    2609             : 
    2610          37 :         return (int)(len1 - len2);
    2611             : }
    2612             : /* }}} */
    2613             : 
    2614           1 : ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2615             : {
    2616             :         size_t len;
    2617             :         int c1, c2;
    2618             : 
    2619           1 :         if (s1 == s2) {
    2620           0 :                 return 0;
    2621             :         }
    2622           1 :         len = MIN(length, MIN(len1, len2));
    2623           4 :         while (len--) {
    2624           2 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2625           2 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2626           2 :                 if (c1 != c2) {
    2627           0 :                         return c1 - c2;
    2628             :                 }
    2629             :         }
    2630             : 
    2631           1 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2632             : }
    2633             : /* }}} */
    2634             : 
    2635           2 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2636             : {
    2637           2 :         return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2638             : }
    2639             : /* }}} */
    2640             : 
    2641           0 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2642             : {
    2643           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));
    2644             : }
    2645             : /* }}} */
    2646             : 
    2647           0 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
    2648             : {
    2649           0 :         return zend_binary_strcasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2650             : }
    2651             : /* }}} */
    2652             : 
    2653           0 : ZEND_API int ZEND_FASTCALL zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2654             : {
    2655           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));
    2656             : }
    2657             : /* }}} */
    2658             : 
    2659      647449 : ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zend_string *s1, zend_string *s2) /* {{{ */
    2660             : {
    2661             :         int ret1, ret2;
    2662             :         int oflow1, oflow2;
    2663      647449 :         zend_long lval1 = 0, lval2 = 0;
    2664      647449 :         double dval1 = 0.0, dval2 = 0.0;
    2665             : 
    2666     1601672 :         if ((ret1 = is_numeric_string_ex(s1->val, s1->len, &lval1, &dval1, 0, &oflow1)) &&
    2667      306774 :                 (ret2 = is_numeric_string_ex(s2->val, s2->len, &lval2, &dval2, 0, &oflow2))) {
    2668             : #if ZEND_ULONG_MAX == 0xFFFFFFFF
    2669             :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
    2670             :                         ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
    2671             :                         || (oflow1 == -1 && dval1 < -9007199254740991.))) {
    2672             : #else
    2673      306628 :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
    2674             : #endif
    2675             :                         /* both values are integers overflown to the same side, and the
    2676             :                          * double comparison may have resulted in crucial accuracy lost */
    2677        1117 :                         goto string_cmp;
    2678             :                 }
    2679      305511 :                 if ((ret1 == IS_DOUBLE) || (ret2 == IS_DOUBLE)) {
    2680      100102 :                         if (ret1 != IS_DOUBLE) {
    2681          34 :                                 if (oflow2) {
    2682             :                                         /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
    2683           2 :                                         return -1 * oflow2;
    2684             :                                 }
    2685          32 :                                 dval1 = (double) lval1;
    2686      100068 :                         } else if (ret2 != IS_DOUBLE) {
    2687          13 :                                 if (oflow1) {
    2688           0 :                                         return oflow1;
    2689             :                                 }
    2690          13 :                                 dval2 = (double) lval2;
    2691      100055 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2692             :                                 /* Both values overflowed and have the same sign,
    2693             :                                  * so a numeric comparison would be inaccurate */
    2694           4 :                                 goto string_cmp;
    2695             :                         }
    2696      100096 :                         dval1 = dval1 - dval2;
    2697      100096 :                         return ZEND_NORMALIZE_BOOL(dval1);
    2698             :                 } else { /* they both have to be long's */
    2699      205409 :                         return lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0);
    2700             :                 }
    2701             :         } else {
    2702             :                 int strcmp_ret;
    2703             : string_cmp:
    2704      341942 :                 strcmp_ret = zend_binary_strcmp(s1->val, s1->len, s2->val, s2->len);
    2705      341942 :                 return ZEND_NORMALIZE_BOOL(strcmp_ret);
    2706             :         }
    2707             : }
    2708             : /* }}} */
    2709             : 
    2710        2900 : static int hash_zval_compare_function(zval *z1, zval *z2) /* {{{ */
    2711             : {
    2712             :         zval result;
    2713             : 
    2714        2900 :         if (compare_function(&result, z1, z2)==FAILURE) {
    2715           0 :                 return 1;
    2716             :         }
    2717        2900 :         return Z_LVAL(result);
    2718             : }
    2719             : /* }}} */
    2720             : 
    2721         871 : ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2) /* {{{ */
    2722             : {
    2723         871 :         return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0);
    2724             : }
    2725             : /* }}} */
    2726             : 
    2727         552 : ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2) /* {{{ */
    2728             : {
    2729         552 :         return zend_compare_symbol_tables(Z_ARRVAL_P(a1), Z_ARRVAL_P(a2));
    2730             : }
    2731             : /* }}} */
    2732             : 
    2733           1 : ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2) /* {{{ */
    2734             : {
    2735           1 :         if (Z_OBJ_P(o1) == Z_OBJ_P(o2)) {
    2736           1 :                 return 0;
    2737             :         }
    2738             : 
    2739           0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2740           0 :                 return 1;
    2741             :         } else {
    2742           0 :                 return Z_OBJ_HT_P(o1)->compare_objects(o1, o2);
    2743             :         }
    2744             : }
    2745             : /* }}} */
    2746             : 
    2747           0 : ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
    2748             : {
    2749             :         zend_string *str;
    2750             : 
    2751           0 :         str = zend_strpprintf(0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
    2752           0 :         ZVAL_NEW_STR(op, str);
    2753           0 : }
    2754             : /* }}} */
    2755             : 
    2756      480202 : ZEND_API zend_string* ZEND_FASTCALL zend_long_to_str(zend_long num) /* {{{ */
    2757             : {
    2758             :         char buf[MAX_LENGTH_OF_LONG + 1];
    2759      480202 :         char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
    2760      960404 :         return zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
    2761             : }
    2762             : /* }}} */
    2763             : 
    2764       32396 : ZEND_API zend_uchar ZEND_FASTCALL is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval) /* {{{ */ {
    2765       64792 :     return is_numeric_string_ex(ZSTR_VAL(str), ZSTR_LEN(str), lval, dval, -1, NULL);
    2766             : }
    2767             : /* }}} */
    2768             : 
    2769      972415 : 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) /* {{{ */
    2770             : {
    2771             :         const char *ptr;
    2772      972415 :         int digits = 0, dp_or_e = 0;
    2773      972415 :         double local_dval = 0.0;
    2774             :         zend_uchar type;
    2775      972415 :         zend_long tmp_lval = 0;
    2776      972415 :         int neg = 0;
    2777             : 
    2778      972415 :         if (!length) {
    2779        1515 :                 return 0;
    2780             :         }
    2781             : 
    2782      970900 :         if (oflow_info != NULL) {
    2783      830261 :                 *oflow_info = 0;
    2784             :         }
    2785             : 
    2786             :         /* Skip any whitespace
    2787             :          * This is much faster than the isspace() function */
    2788     1943748 :         while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
    2789        1948 :                 str++;
    2790        1948 :                 length--;
    2791             :         }
    2792      970900 :         ptr = str;
    2793             : 
    2794      970900 :         if (*ptr == '-') {
    2795        2097 :                 neg = 1;
    2796        2097 :                 ptr++;
    2797      968803 :         } else if (*ptr == '+') {
    2798         743 :                 ptr++;
    2799             :         }
    2800             : 
    2801     1532880 :         if (ZEND_IS_DIGIT(*ptr)) {
    2802             :                 /* Skip any leading 0s */
    2803     1803039 :                 while (*ptr == '0') {
    2804      267779 :                         ptr++;
    2805             :                 }
    2806             : 
    2807             :                 /* Count the number of digits. If a decimal point/exponent is found,
    2808             :                  * it's a double. Otherwise, if there's a dval or no need to check for
    2809             :                  * a full match, stop when there are too many digits for a long */
    2810    10908860 :                 for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
    2811             : check_digits:
    2812     5452246 :                         if (ZEND_IS_DIGIT(*ptr)) {
    2813     4686800 :                                 tmp_lval = tmp_lval * 10 + (*ptr) - '0';
    2814     4686800 :                                 continue;
    2815      765446 :                         } else if (*ptr == '.' && dp_or_e < 1) {
    2816             :                                 goto process_double;
    2817      562478 :                         } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
    2818         535 :                                 const char *e = ptr + 1;
    2819             : 
    2820         535 :                                 if (*e == '-' || *e == '+') {
    2821           9 :                                         ptr = e++;
    2822             :                                 }
    2823         535 :                                 if (ZEND_IS_DIGIT(*e)) {
    2824         491 :                                         goto process_double;
    2825             :                                 }
    2826             :                         }
    2827             : 
    2828      561987 :                         break;
    2829             :                 }
    2830             : 
    2831      564227 :                 if (digits >= MAX_LENGTH_OF_LONG) {
    2832        2247 :                         if (oflow_info != NULL) {
    2833        2237 :                                 *oflow_info = *str == '-' ? -1 : 1;
    2834             :                         }
    2835        2247 :                         dp_or_e = -1;
    2836        2247 :                         goto process_double;
    2837             :                 }
    2838      409080 :         } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
    2839             : process_double:
    2840      205866 :                 type = IS_DOUBLE;
    2841             : 
    2842             :                 /* If there's a dval, do the conversion; else continue checking
    2843             :                  * the digits if we need to check for a full match */
    2844      205866 :                 if (dval) {
    2845      205803 :                         local_dval = zend_strtod(str, &ptr);
    2846          63 :                 } else if (allow_errors != 1 && dp_or_e != -1) {
    2847          56 :                         dp_or_e = (*ptr++ == '.') ? 1 : 2;
    2848          56 :                         goto check_digits;
    2849             :                 }
    2850             :         } else {
    2851      203110 :                 return 0;
    2852             :         }
    2853             : 
    2854      767790 :         if (ptr != str + length) {
    2855       15577 :                 if (!allow_errors) {
    2856       14029 :                         return 0;
    2857             :                 }
    2858        1548 :                 if (allow_errors == -1) {
    2859        1326 :                         zend_error(E_NOTICE, "A non well formed numeric value encountered");
    2860             :                 }
    2861             :         }
    2862             : 
    2863      753761 :         if (type == IS_LONG) {
    2864      548689 :                 if (digits == MAX_LENGTH_OF_LONG - 1) {
    2865         174 :                         int cmp = strcmp(&ptr[-digits], long_min_digits);
    2866             : 
    2867         174 :                         if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
    2868           2 :                                 if (dval) {
    2869           2 :                                         *dval = zend_strtod(str, NULL);
    2870             :                                 }
    2871           2 :                                 if (oflow_info != NULL) {
    2872           2 :                                         *oflow_info = *str == '-' ? -1 : 1;
    2873             :                                 }
    2874             : 
    2875           2 :                                 return IS_DOUBLE;
    2876             :                         }
    2877             :                 }
    2878             : 
    2879      548687 :                 if (lval) {
    2880      548612 :                         if (neg) {
    2881         626 :                                 tmp_lval = -tmp_lval;
    2882             :                         }
    2883      548612 :                         *lval = tmp_lval;
    2884             :                 }
    2885             : 
    2886      548687 :                 return IS_LONG;
    2887             :         } else {
    2888      205072 :                 if (dval) {
    2889      205038 :                         *dval = local_dval;
    2890             :                 }
    2891             : 
    2892      205072 :                 return IS_DOUBLE;
    2893             :         }
    2894             : }
    2895             : /* }}} */
    2896             : 
    2897             : /* 
    2898             :  * String matching - Sunday algorithm
    2899             :  * http://www.iti.fh-flensburg.de/lang/algorithmen/pattern/sundayen.htm
    2900             :  */
    2901             : static zend_always_inline void zend_memnstr_ex_pre(unsigned int td[], const char *needle, size_t needle_len, int reverse) /* {{{ */ {
    2902             :         int i;
    2903             : 
    2904     4098893 :         for (i = 0; i < 256; i++) {
    2905     4082944 :                 td[i] = needle_len + 1;
    2906             :         }
    2907             : 
    2908       15949 :         if (reverse) {
    2909           0 :                 for (i = needle_len - 1; i >= 0; i--) {
    2910           0 :                         td[(unsigned char)needle[i]] = i + 1;
    2911             :                 }
    2912             :         } else {
    2913             :                 size_t i;
    2914             : 
    2915      248484 :                 for (i = 0; i < needle_len; i++) {
    2916      232535 :                         td[(unsigned char)needle[i]] = (int)needle_len - i;
    2917             :                 }
    2918             :         }
    2919             : }
    2920             : /* }}} */
    2921             : 
    2922       15949 : ZEND_API const char* ZEND_FASTCALL zend_memnstr_ex(const char *haystack, const char *needle, size_t needle_len, const char *end) /* {{{ */
    2923             : {
    2924             :         unsigned int td[256];
    2925             :         register size_t i;
    2926             :         register const char *p;
    2927             : 
    2928       15949 :         if (needle_len == 0 || (end - haystack) == 0) {
    2929           0 :                 return NULL;
    2930             :         }
    2931             : 
    2932             :         zend_memnstr_ex_pre(td, needle, needle_len, 0);
    2933             : 
    2934       15949 :         p = haystack;
    2935       15949 :         end -= needle_len;
    2936             : 
    2937     5449325 :         while (p <= end) {
    2938     6575617 :                 for (i = 0; i < needle_len; i++) {
    2939     6571118 :                         if (needle[i] != p[i]) {
    2940     5418824 :                                 break;
    2941             :                         }
    2942             :                 }
    2943     5423323 :                 if (i == needle_len) {
    2944        4499 :                         return p;
    2945             :                 }
    2946     5418824 :                 if (UNEXPECTED(p == end)) {
    2947        1397 :                         return NULL;
    2948             :                 }
    2949     5417427 :                 p += td[(unsigned char)(p[needle_len])];
    2950             :         }
    2951             : 
    2952       10053 :         return NULL;
    2953             : }
    2954             : /* }}} */
    2955             : 
    2956           0 : ZEND_API const char* ZEND_FASTCALL zend_memnrstr_ex(const char *haystack, const char *needle, size_t needle_len, const char *end) /* {{{ */
    2957             : {
    2958             :         unsigned int td[256];
    2959             :         register size_t i;
    2960             :         register const char *p;
    2961             : 
    2962           0 :         if (needle_len == 0 || (end - haystack) == 0) {
    2963           0 :                 return NULL;
    2964             :         }
    2965             : 
    2966             :         zend_memnstr_ex_pre(td, needle, needle_len, 1);
    2967             : 
    2968           0 :         p = end;
    2969           0 :         p -= needle_len;
    2970             : 
    2971           0 :         while (p >= haystack) {
    2972           0 :                 for (i = 0; i < needle_len; i++) {
    2973           0 :                         if (needle[i] != p[i]) {
    2974           0 :                                 break;
    2975             :                         }
    2976             :                 }
    2977             : 
    2978           0 :                 if (i == needle_len) {
    2979           0 :                         return (const char *)p;
    2980             :                 }
    2981             :                 
    2982           0 :                 if (UNEXPECTED(p == haystack)) {
    2983           0 :                         return NULL;
    2984             :                 }
    2985             : 
    2986           0 :                 p -= td[(unsigned char)(p[-1])];
    2987             :         }
    2988             : 
    2989           0 :         return NULL;
    2990             : }
    2991             : /* }}} */
    2992             : 
    2993             : #if !ZEND_DVAL_TO_LVAL_CAST_OK
    2994             : # if SIZEOF_ZEND_LONG == 4
    2995             : ZEND_API zend_long ZEND_FASTCALL zend_dval_to_lval_slow(double d)
    2996             : {
    2997             :         double  two_pow_32 = pow(2., 32.),
    2998             :                         dmod;
    2999             : 
    3000             :         dmod = fmod(d, two_pow_32);
    3001             :         if (dmod < 0) {
    3002             :                 /* we're going to make this number positive; call ceil()
    3003             :                  * to simulate rounding towards 0 of the negative number */
    3004             :                 dmod = ceil(dmod);// + two_pow_32;
    3005             :         }
    3006             :         return (zend_long)(zend_ulong)dmod;
    3007             : }
    3008             : #else
    3009         140 : ZEND_API zend_long ZEND_FASTCALL zend_dval_to_lval_slow(double d)
    3010             : {
    3011         140 :         double  two_pow_64 = pow(2., 64.),
    3012             :                         dmod;
    3013             : 
    3014         140 :         dmod = fmod(d, two_pow_64);
    3015         140 :         if (dmod < 0) {
    3016             :                 /* no need to call ceil; original double must have had no
    3017             :                  * fractional part, hence dmod does not have one either */
    3018           7 :                 dmod += two_pow_64;
    3019             :         }
    3020         140 :         return (zend_long)(zend_ulong)dmod;
    3021             : }
    3022             : #endif
    3023             : #endif
    3024             : 
    3025             : /*
    3026             :  * Local variables:
    3027             :  * tab-width: 4
    3028             :  * c-basic-offset: 4
    3029             :  * indent-tabs-mode: t
    3030             :  * End:
    3031             :  */

Generated by: LCOV version 1.10

Generated at Wed, 20 Jul 2016 02:56:15 +0000 (4 days ago)

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