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: 1124 1316 85.4 %
Date: 2015-05-21 Functions: 74 84 88.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:58:53 +0000 (7 days ago)

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