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: 1185 1392 85.1 %
Date: 2016-06-25 Functions: 75 86 87.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 25 Jun 2016 07:08:53 +0000 (3 days ago)

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