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: 1180 1377 85.7 %
Date: 2015-08-25 Functions: 76 86 88.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Tue, 25 Aug 2015 07:24:15 +0000 (3 days ago)

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