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: 1138 1343 84.7 %
Date: 2015-01-26 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       62855 : ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
      83             : {
      84             :         int retval;
      85             : 
      86       62855 :         if (!str_len) {
      87       41558 :                 str_len = (int)strlen(str);
      88             :         }
      89       62855 :         retval = ZEND_STRTOL(str, NULL, 0);
      90       62855 :         if (str_len>0) {
      91       42073 :                 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       62855 :         return retval;
     107             : }
     108             : /* }}} */
     109             : 
     110     1350423 : ZEND_API zend_long zend_atol(const char *str, int str_len) /* {{{ */
     111             : {
     112             :         zend_long retval;
     113             : 
     114     1350423 :         if (!str_len) {
     115       20647 :                 str_len = (int)strlen(str);
     116             :         }
     117     1350423 :         retval = ZEND_STRTOL(str, NULL, 0);
     118     1350423 :         if (str_len>0) {
     119     1329776 :                 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       62314 :                                 retval *= 1024;
     127             :                                 /* break intentionally missing */
     128             :                         case 'k':
     129             :                         case 'K':
     130       83101 :                                 retval *= 1024;
     131             :                                 break;
     132             :                 }
     133             :         }
     134     1350423 :         return retval;
     135             : }
     136             : /* }}} */
     137             : 
     138      203356 : ZEND_API void convert_scalar_to_number(zval *op) /* {{{ */
     139             : {
     140             : try_again:
     141      203356 :         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      101129 :                                 str = Z_STR_P(op);
     155      202258 :                                 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      101129 :                                 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      203353 : }
     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       42963 : ZEND_API void convert_to_long(zval *op) /* {{{ */
     276             : {
     277       42963 :         if (Z_TYPE_P(op) != IS_LONG) {
     278       22292 :                 convert_to_long_base(op, 10);
     279             :         }
     280       42963 : }
     281             : /* }}} */
     282             : 
     283       26006 : ZEND_API void convert_to_long_base(zval *op, int base) /* {{{ */
     284             : {
     285             :         zend_long tmp;
     286             : 
     287       26006 :         switch (Z_TYPE_P(op)) {
     288             :                 case IS_NULL:
     289             :                 case IS_FALSE:
     290         331 :                         ZVAL_LONG(op, 0);
     291         331 :                         break;
     292             :                 case IS_TRUE:
     293         943 :                         ZVAL_LONG(op, 1);
     294         943 :                         break;
     295             :                 case IS_RESOURCE: {
     296          13 :                                 zend_long l = Z_RES_HANDLE_P(op);
     297          13 :                                 zval_ptr_dtor(op);
     298          13 :                                 ZVAL_LONG(op, l);
     299             :                         }
     300             :                         /* break missing intentionally */
     301          13 :                         Z_TYPE_INFO_P(op) = IS_LONG;
     302          13 :                         break;
     303             :                 case IS_LONG:
     304        2830 :                         break;
     305             :                 case IS_DOUBLE:
     306        1936 :                         ZVAL_LONG(op, zend_dval_to_lval(Z_DVAL_P(op)));
     307         968 :                         break;
     308             :                 case IS_STRING:
     309             :                         {
     310       20831 :                                 zend_string *str = Z_STR_P(op);
     311             : 
     312       20831 :                                 ZVAL_LONG(op, ZEND_STRTOL(str->val, NULL, base));
     313             :                                 zend_string_release(str);
     314             :                         }
     315       20831 :                         break;
     316             :                 case IS_ARRAY:
     317          57 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     318             :                         zval_dtor(op);
     319          57 :                         ZVAL_LONG(op, tmp);
     320          57 :                         break;
     321             :                 case IS_OBJECT:
     322             :                         {
     323             :                                 zval dst;
     324             : 
     325          33 :                                 convert_object_to_type(op, &dst, IS_LONG, convert_to_long);
     326             :                                 zval_dtor(op);
     327             : 
     328          33 :                                 if (Z_TYPE(dst) == IS_LONG) {
     329          33 :                                         ZVAL_COPY_VALUE(op, &dst);
     330             :                                 } else {
     331           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name->val);
     332             : 
     333           0 :                                         ZVAL_LONG(op, 1);
     334             :                                 }
     335          33 :                                 return;
     336             :                         }
     337             :                 EMPTY_SWITCH_DEFAULT_CASE()
     338             :         }
     339             : }
     340             : /* }}} */
     341             : 
     342        3183 : ZEND_API void convert_to_double(zval *op) /* {{{ */
     343             : {
     344             :         double tmp;
     345             : 
     346        3183 :         switch (Z_TYPE_P(op)) {
     347             :                 case IS_NULL:
     348             :                 case IS_FALSE:
     349          17 :                         ZVAL_DOUBLE(op, 0.0);
     350          17 :                         break;
     351             :                 case IS_TRUE:
     352           5 :                         ZVAL_DOUBLE(op, 1.0);
     353           5 :                         break;
     354             :                 case IS_RESOURCE: {
     355          15 :                                 double d = (double) Z_RES_HANDLE_P(op);
     356          15 :                                 zval_ptr_dtor(op);
     357          15 :                                 ZVAL_DOUBLE(op, d);
     358             :                         }
     359          15 :                         break;
     360             :                 case IS_LONG:
     361        1956 :                         ZVAL_DOUBLE(op, (double) Z_LVAL_P(op));
     362        1956 :                         break;
     363             :                 case IS_DOUBLE:
     364        1101 :                         break;
     365             :                 case IS_STRING:
     366             :                         {
     367          77 :                                 zend_string *str = Z_STR_P(op);
     368             : 
     369          77 :                                 ZVAL_DOUBLE(op, zend_strtod(str->val, NULL));
     370             :                                 zend_string_release(str);
     371             :                         }
     372          77 :                         break;
     373             :                 case IS_ARRAY:
     374           8 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     375             :                         zval_dtor(op);
     376           8 :                         ZVAL_DOUBLE(op, tmp);
     377           8 :                         break;
     378             :                 case IS_OBJECT:
     379             :                         {
     380             :                                 zval dst;
     381             : 
     382           4 :                                 convert_object_to_type(op, &dst, IS_DOUBLE, convert_to_double);
     383             :                                 zval_dtor(op);
     384             : 
     385           4 :                                 if (Z_TYPE(dst) == IS_DOUBLE) {
     386           4 :                                         ZVAL_COPY_VALUE(op, &dst);
     387             :                                 } else {
     388           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to float", Z_OBJCE_P(op)->name->val);
     389             : 
     390           0 :                                         ZVAL_DOUBLE(op, 1.0);
     391             :                                 }
     392             :                                 break;
     393             :                         }
     394             :                 EMPTY_SWITCH_DEFAULT_CASE()
     395             :         }
     396        3183 : }
     397             : /* }}} */
     398             : 
     399         914 : ZEND_API void convert_to_null(zval *op) /* {{{ */
     400             : {
     401         914 :         if (Z_TYPE_P(op) == IS_OBJECT) {
     402           3 :                 if (Z_OBJ_HT_P(op)->cast_object) {
     403             :                         zval org;
     404             : 
     405           3 :                         ZVAL_COPY_VALUE(&org, op);
     406           3 :                         if (Z_OBJ_HT_P(op)->cast_object(&org, op, IS_NULL) == SUCCESS) {
     407             :                                 zval_dtor(&org);
     408           0 :                                 return;
     409             :                         }
     410           3 :                         ZVAL_COPY_VALUE(op, &org);
     411             :                 }
     412             :         }
     413             : 
     414             :         zval_dtor(op);
     415         914 :         ZVAL_NULL(op);
     416             : }
     417             : /* }}} */
     418             : 
     419         729 : ZEND_API void convert_to_boolean(zval *op) /* {{{ */
     420             : {
     421             :         int tmp;
     422             : 
     423         729 :         switch (Z_TYPE_P(op)) {
     424             :                 case IS_FALSE:
     425             :                 case IS_TRUE:
     426         320 :                         break;
     427             :                 case IS_NULL:
     428           5 :                         ZVAL_FALSE(op);
     429           5 :                         break;
     430             :                 case IS_RESOURCE: {
     431          35 :                                 zend_long l = (Z_RES_HANDLE_P(op) ? 1 : 0);
     432             : 
     433          35 :                                 zval_ptr_dtor(op);
     434          35 :                                 ZVAL_BOOL(op, l);
     435             :                         }
     436          35 :                         break;
     437             :                 case IS_LONG:
     438         318 :                         ZVAL_BOOL(op, Z_LVAL_P(op) ? 1 : 0);
     439         318 :                         break;
     440             :                 case IS_DOUBLE:
     441           6 :                         ZVAL_BOOL(op, Z_DVAL_P(op) ? 1 : 0);
     442           6 :                         break;
     443             :                 case IS_STRING:
     444             :                         {
     445          19 :                                 zend_string *str = Z_STR_P(op);
     446             : 
     447          43 :                                 if (str->len == 0
     448          41 :                                         || (str->len == 1 && str->val[0] == '0')) {
     449           2 :                                         ZVAL_FALSE(op);
     450             :                                 } else {
     451          17 :                                         ZVAL_TRUE(op);
     452             :                                 }
     453             :                                 zend_string_release(str);
     454             :                         }
     455          19 :                         break;
     456             :                 case IS_ARRAY:
     457          22 :                         tmp = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     458             :                         zval_dtor(op);
     459          22 :                         ZVAL_BOOL(op, tmp);
     460          22 :                         break;
     461             :                 case IS_OBJECT:
     462             :                         {
     463             :                                 zval dst;
     464             : 
     465           4 :                                 convert_object_to_type(op, &dst, _IS_BOOL, convert_to_boolean);
     466             :                                 zval_dtor(op);
     467             : 
     468          12 :                                 if (Z_TYPE(dst) == IS_FALSE || Z_TYPE(dst) == IS_TRUE) {
     469           4 :                                         ZVAL_COPY_VALUE(op, &dst);
     470             :                                 } else {
     471           0 :                                         ZVAL_TRUE(op);
     472             :                                 }
     473             :                                 break;
     474             :                         }
     475             :                 EMPTY_SWITCH_DEFAULT_CASE()
     476             :         }
     477         729 : }
     478             : /* }}} */
     479             : 
     480          13 : ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     481             : {
     482          13 :         _convert_to_string(op ZEND_FILE_LINE_CC);
     483          13 : }
     484             : /* }}} */
     485             : 
     486       60071 : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
     487             : {
     488       60071 :         switch (Z_TYPE_P(op)) {
     489             :                 case IS_UNDEF:
     490             :                 case IS_NULL:
     491             :                 case IS_FALSE: {
     492        4092 :                                         ZVAL_EMPTY_STRING(op);
     493        4092 :                         break;
     494             :                 }
     495             :                 case IS_TRUE:
     496        1612 :                         ZVAL_NEW_STR(op, zend_string_init("1", 1, 0));
     497         806 :                         break;
     498             :                 case IS_STRING:
     499           0 :                         break;
     500             :                 case IS_RESOURCE: {
     501             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     502          43 :                         int len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
     503          86 :                         ZVAL_NEW_STR(op, zend_string_init(buf, len, 0));
     504          43 :                         break;
     505             :                 }
     506             :                 case IS_LONG: {
     507       52925 :                         ZVAL_NEW_STR(op, zend_long_to_str(Z_LVAL_P(op)));
     508       52925 :                         break;
     509             :                 }
     510             :                 case IS_DOUBLE: {
     511             :                         zend_string *str;
     512        1978 :                         double dval = Z_DVAL_P(op);
     513             : 
     514        1978 :                         str = zend_strpprintf(0, "%.*G", (int) EG(precision), dval);
     515             :                         /* %G already handles removing trailing zeros from the fractional part, yay */
     516        1978 :                         ZVAL_NEW_STR(op, str);
     517        1978 :                         break;
     518             :                 }
     519             :                 case IS_ARRAY:
     520         179 :                         zend_error(E_NOTICE, "Array to string conversion");
     521             :                         zval_dtor(op);
     522         358 :                         ZVAL_NEW_STR(op, zend_string_init("Array", sizeof("Array")-1, 0));
     523         179 :                         break;
     524             :                 case IS_OBJECT: {
     525             :                         zval dst;
     526             : 
     527          48 :                         convert_object_to_type(op, &dst, IS_STRING, convert_to_string);
     528             : 
     529          40 :                         if (Z_TYPE(dst) == IS_STRING) {
     530             :                                 zval_dtor(op);
     531          33 :                                 ZVAL_COPY_VALUE(op, &dst);
     532             :                         } else {
     533           7 :                                 zend_error(E_NOTICE, "Object of class %s to string conversion", Z_OBJCE_P(op)->name->val);
     534             :                                 zval_dtor(op);
     535          14 :                                 ZVAL_NEW_STR(op, zend_string_init("Object", sizeof("Object")-1, 0));
     536             :                         }
     537             :                         break;
     538             :                 }
     539             :                 EMPTY_SWITCH_DEFAULT_CASE()
     540             :         }
     541       60063 : }
     542             : /* }}} */
     543             : 
     544         119 : static void convert_scalar_to_array(zval *op) /* {{{ */
     545             : {
     546             :         zval entry;
     547             : 
     548         119 :         ZVAL_COPY_VALUE(&entry, op);
     549             : 
     550         119 :         ZVAL_NEW_ARR(op);
     551         119 :         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     552         119 :         zend_hash_index_add_new(Z_ARRVAL_P(op), 0, &entry);
     553         119 : }
     554             : /* }}} */
     555             : 
     556         174 : ZEND_API void convert_to_array(zval *op) /* {{{ */
     557             : {
     558             : 
     559         174 :         switch (Z_TYPE_P(op)) {
     560             :                 case IS_ARRAY:
     561          21 :                         break;
     562             : /* OBJECTS_OPTIMIZE */
     563             :                 case IS_OBJECT:
     564          19 :                         if (Z_OBJCE_P(op) == zend_ce_closure) {
     565           3 :                                 convert_scalar_to_array(op);
     566             :                         } else {
     567          16 :                                 if (Z_OBJ_HT_P(op)->get_properties) {
     568          16 :                                         HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op);
     569          16 :                                         if (obj_ht) {
     570             :                                                 zval arr;
     571          16 :                                                 ZVAL_NEW_ARR(&arr);
     572          16 :                                                 zend_array_dup(Z_ARRVAL(arr), obj_ht);
     573             :                                                 zval_dtor(op);
     574          16 :                                                 ZVAL_COPY_VALUE(op, &arr);
     575          16 :                                                 return;
     576             :                                         }
     577             :                                 } else {
     578             :                                         zval dst;
     579           0 :                                         convert_object_to_type(op, &dst, IS_ARRAY, convert_to_array);
     580             : 
     581           0 :                                         if (Z_TYPE(dst) == IS_ARRAY) {
     582             :                                                 zval_dtor(op);
     583           0 :                                                 ZVAL_COPY_VALUE(op, &dst);
     584           0 :                                                 return;
     585             :                                         }
     586             :                                 }
     587             : 
     588             :                                 zval_dtor(op);
     589           0 :                                 array_init(op);
     590             :                         }
     591           3 :                         break;
     592             :                 case IS_NULL:
     593          18 :                         ZVAL_NEW_ARR(op);
     594          18 :                         zend_hash_init(Z_ARRVAL_P(op), 8, NULL, ZVAL_PTR_DTOR, 0);
     595          18 :                         break;
     596             :                 default:
     597         116 :                         convert_scalar_to_array(op);
     598             :                         break;
     599             :         }
     600             : }
     601             : /* }}} */
     602             : 
     603         124 : ZEND_API void convert_to_object(zval *op) /* {{{ */
     604             : {
     605             : 
     606         124 :         switch (Z_TYPE_P(op)) {
     607             :                 case IS_ARRAY:
     608             :                         {
     609          81 :                                 HashTable *properties = emalloc(sizeof(HashTable));
     610          81 :                                 zend_array *arr = Z_ARR_P(op);
     611             : 
     612          81 :                                 memcpy(properties, Z_ARRVAL_P(op), sizeof(HashTable));
     613          81 :                                 object_and_properties_init(op, zend_standard_class_def, properties);
     614          81 :                                 if (--GC_REFCOUNT(arr) == 0) {
     615          81 :                                         efree_size(arr, sizeof(zend_array));
     616             :                                 }
     617          81 :                                 break;
     618             :                         }
     619             :                 case IS_OBJECT:
     620           3 :                         break;
     621             :                 case IS_NULL:
     622           3 :                         object_init(op);
     623           3 :                         break;
     624             :                 default: {
     625             :                         zval tmp;
     626          37 :                         ZVAL_COPY_VALUE(&tmp, op);
     627          37 :                         object_init(op);
     628          37 :                         zend_hash_str_add_new(Z_OBJPROP_P(op), "scalar", sizeof("scalar")-1, &tmp);
     629             :                         break;
     630             :                 }
     631             :         }
     632         124 : }
     633             : /* }}} */
     634             : 
     635           0 : ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */
     636             : {
     637             :         zval *arg;
     638             :         va_list ap;
     639             : 
     640           0 :         va_start(ap, argc);
     641             : 
     642           0 :         while (argc--) {
     643           0 :                 arg = va_arg(ap, zval *);
     644           0 :                 convert_to_long_ex(arg);
     645             :         }
     646             : 
     647           0 :         va_end(ap);
     648           0 : }
     649             : /* }}} */
     650             : 
     651           0 : ZEND_API void multi_convert_to_double_ex(int argc, ...) /* {{{ */
     652             : {
     653             :         zval *arg;
     654             :         va_list ap;
     655             : 
     656           0 :         va_start(ap, argc);
     657             : 
     658           0 :         while (argc--) {
     659           0 :                 arg = va_arg(ap, zval *);
     660           0 :                 convert_to_double_ex(arg);
     661             :         }
     662             : 
     663           0 :         va_end(ap);
     664           0 : }
     665             : /* }}} */
     666             : 
     667           0 : ZEND_API void multi_convert_to_string_ex(int argc, ...) /* {{{ */
     668             : {
     669             :         zval *arg;
     670             :         va_list ap;
     671             : 
     672           0 :         va_start(ap, argc);
     673             : 
     674           0 :         while (argc--) {
     675           0 :                 arg = va_arg(ap, zval *);
     676           0 :                 convert_to_string_ex(arg);
     677             :         }
     678             : 
     679           0 :         va_end(ap);
     680           0 : }
     681             : /* }}} */
     682             : 
     683       12882 : ZEND_API zend_long _zval_get_long_func(zval *op) /* {{{ */
     684             : {
     685             : try_again:
     686       12882 :         switch (Z_TYPE_P(op)) {
     687             :                 case IS_NULL:
     688             :                 case IS_FALSE:
     689         777 :                         return 0;
     690             :                 case IS_TRUE:
     691        1957 :                         return 1;
     692             :                 case IS_RESOURCE:
     693          87 :                         return Z_RES_HANDLE_P(op);
     694             :                 case IS_LONG:
     695           0 :                         return Z_LVAL_P(op);
     696             :                 case IS_DOUBLE:
     697        3672 :                         return zend_dval_to_lval(Z_DVAL_P(op));
     698             :                 case IS_STRING:
     699        7365 :                         return ZEND_STRTOL(Z_STRVAL_P(op), NULL, 10);
     700             :                 case IS_ARRAY:
     701         832 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1 : 0;
     702             :                 case IS_OBJECT:
     703             :                         {
     704             :                                 zval dst;
     705          24 :                                 convert_object_to_type(op, &dst, IS_LONG, convert_to_long);
     706          24 :                                 if (Z_TYPE(dst) == IS_LONG) {
     707          24 :                                         return Z_LVAL(dst);
     708             :                                 } else {
     709           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to int", Z_OBJCE_P(op)->name->val);
     710           0 :                                         return 1;
     711             :                                 }
     712             :                         }
     713             :                 case IS_REFERENCE:
     714           4 :                         op = Z_REFVAL_P(op);
     715           4 :                         goto try_again;
     716             :                 EMPTY_SWITCH_DEFAULT_CASE()
     717             :         }
     718           0 :         return 0;
     719             : }
     720             : /* }}} */
     721             : 
     722      204767 : ZEND_API double _zval_get_double_func(zval *op) /* {{{ */
     723             : {
     724             : try_again:
     725      204767 :         switch (Z_TYPE_P(op)) {
     726             :                 case IS_NULL:
     727             :                 case IS_FALSE:
     728         127 :                         return 0.0;
     729             :                 case IS_TRUE:
     730         125 :                         return 1.0;
     731             :                 case IS_RESOURCE:
     732          33 :                         return (double) Z_RES_HANDLE_P(op);
     733             :                 case IS_LONG:
     734      203481 :                         return (double) Z_LVAL_P(op);
     735             :                 case IS_DOUBLE:
     736           0 :                         return Z_DVAL_P(op);
     737             :                 case IS_STRING:
     738         607 :                         return zend_strtod(Z_STRVAL_P(op), NULL);
     739             :                 case IS_ARRAY:
     740         371 :                         return zend_hash_num_elements(Z_ARRVAL_P(op)) ? 1.0 : 0.0;
     741             :                 case IS_OBJECT:
     742             :                         {
     743             :                                 zval dst;
     744          11 :                                 convert_object_to_type(op, &dst, IS_DOUBLE, convert_to_double);
     745             : 
     746          11 :                                 if (Z_TYPE(dst) == IS_DOUBLE) {
     747          11 :                                         return Z_DVAL(dst);
     748             :                                 } else {
     749           0 :                                         zend_error(E_NOTICE, "Object of class %s could not be converted to double", Z_OBJCE_P(op)->name->val);
     750             : 
     751           0 :                                         return 1.0;
     752             :                                 }
     753             :                         }
     754             :                 case IS_REFERENCE:
     755          12 :                         op = Z_REFVAL_P(op);
     756          12 :                         goto try_again;
     757             :                 EMPTY_SWITCH_DEFAULT_CASE()
     758             :         }
     759           0 :         return 0.0;
     760             : }
     761             : /* }}} */
     762             : 
     763     1316697 : ZEND_API zend_string *_zval_get_string_func(zval *op) /* {{{ */
     764             : {
     765             : try_again:
     766     1316697 :         switch (Z_TYPE_P(op)) {
     767             :                 case IS_UNDEF:
     768             :                 case IS_NULL:
     769             :                 case IS_FALSE:
     770        3430 :                         return STR_EMPTY_ALLOC();
     771             :                 case IS_TRUE:
     772        1379 :                         return zend_string_init("1", 1, 0);
     773             :                 case IS_RESOURCE: {
     774             :                         char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG];
     775             :                         int len;
     776             : 
     777         637 :                         len = snprintf(buf, sizeof(buf), "Resource id #" ZEND_LONG_FMT, (zend_long)Z_RES_HANDLE_P(op));
     778        1274 :                         return zend_string_init(buf, len, 0);
     779             :                 }
     780             :                 case IS_LONG: {
     781      333546 :                         return zend_long_to_str(Z_LVAL_P(op));
     782             :                 }
     783             :                 case IS_DOUBLE: {
     784        6084 :                         return zend_strpprintf(0, "%.*G", (int) EG(precision), Z_DVAL_P(op));
     785             :                 }
     786             :                 case IS_ARRAY:
     787         845 :                         zend_error(E_NOTICE, "Array to string conversion");
     788         845 :                         return zend_string_init("Array", sizeof("Array")-1, 0);
     789             :                 case IS_OBJECT: {
     790             :                         zval tmp;
     791      103555 :                         if (Z_OBJ_HT_P(op)->cast_object) {
     792      103555 :                                 if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_STRING) == SUCCESS) {
     793      103501 :                                         return Z_STR(tmp);
     794             :                                 }
     795           0 :                         } else if (Z_OBJ_HT_P(op)->get) {
     796           0 :                                 zval *z = Z_OBJ_HT_P(op)->get(op, &tmp);
     797           0 :                                 if (Z_TYPE_P(z) != IS_OBJECT) {
     798           0 :                                         zend_string *str = zval_get_string(z);
     799           0 :                                         zval_ptr_dtor(z);
     800           0 :                                         return str;
     801             :                                 }
     802           0 :                                 zval_ptr_dtor(z);
     803             :                         }
     804          50 :                         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);
     805          46 :                         return STR_EMPTY_ALLOC();
     806             :                 }
     807             :                 case IS_REFERENCE:
     808      440789 :                         op = Z_REFVAL_P(op);
     809      440789 :                         goto try_again;
     810             :                 case IS_STRING:
     811      852864 :                         return zend_string_copy(Z_STR_P(op));
     812             :                 EMPTY_SWITCH_DEFAULT_CASE()
     813             :         }
     814           0 :         return NULL;
     815             : }
     816             : /* }}} */
     817             : 
     818      755706 : ZEND_API int add_function(zval *result, zval *op1, zval *op2) /* {{{ */
     819             : {
     820             :         zval op1_copy, op2_copy;
     821      755706 :         int converted = 0;
     822             : 
     823             :         while (1) {
     824     1512414 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     825             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     826      755384 :                                 zend_long lval = Z_LVAL_P(op1) + Z_LVAL_P(op2);
     827             : 
     828             :                                 /* check for overflow by comparing sign bits */
     829     1510680 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     830     1510671 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     831             : 
     832           9 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
     833             :                                 } else {
     834      755375 :                                         ZVAL_LONG(result, lval);
     835             :                                 }
     836      755384 :                                 return SUCCESS;
     837             :                         }
     838             : 
     839             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     840         176 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     841         176 :                                 return SUCCESS;
     842             : 
     843             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     844          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     845          61 :                                 return SUCCESS;
     846             : 
     847             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     848          64 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     849          64 :                                 return SUCCESS;
     850             : 
     851             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
     852          12 :                                 if ((result == op1) && (result == op2)) {
     853             :                                         /* $a += $a */
     854           1 :                                         return SUCCESS;
     855             :                                 }
     856          11 :                                 if (result != op1) {
     857          10 :                                         ZVAL_DUP(result, op1);
     858             :                                 }
     859          11 :                                 zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0);
     860          11 :                                 return SUCCESS;
     861             : 
     862             :                         default:
     863         510 :                                 if (Z_ISREF_P(op1)) {
     864          23 :                                         op1 = Z_REFVAL_P(op1);
     865         487 :                                 } else if (Z_ISREF_P(op2)) {
     866          18 :                                         op2 = Z_REFVAL_P(op2);
     867         469 :                                 } else if (!converted) {
     868        1392 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_ADD, add_function);
     869             : 
     870        1248 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     871        1159 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     872         460 :                                         converted = 1;
     873             :                                 } else {
     874           4 :                                         zend_error(E_ERROR, "Unsupported operand types");
     875           0 :                                         return FAILURE; /* unknown datatype */
     876             :                                 }
     877             :                 }
     878         501 :         }
     879             : }
     880             : /* }}} */
     881             : 
     882       62974 : ZEND_API int sub_function(zval *result, zval *op1, zval *op2) /* {{{ */
     883             : {
     884             :         zval op1_copy, op2_copy;
     885       62974 :         int converted = 0;
     886             : 
     887             :         while (1) {
     888      126436 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     889             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     890       61213 :                                 zend_long lval = Z_LVAL_P(op1) - Z_LVAL_P(op2);
     891             : 
     892             :                                 /* check for overflow by comparing sign bits */
     893       61382 :                                 if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     894       61380 :                                         && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
     895             : 
     896           2 :                                         ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
     897             :                                 } else {
     898       61211 :                                         ZVAL_LONG(result, lval);
     899             :                                 }
     900       61213 :                                 return SUCCESS;
     901             : 
     902             :                         }
     903             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     904        1670 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     905        1670 :                                 return SUCCESS;
     906             : 
     907             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     908          45 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     909          45 :                                 return SUCCESS;
     910             : 
     911             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     912          39 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     913          39 :                                 return SUCCESS;
     914             : 
     915             :                         default:
     916         251 :                                 if (Z_ISREF_P(op1)) {
     917           8 :                                         op1 = Z_REFVAL_P(op1);
     918         243 :                                 } else if (Z_ISREF_P(op2)) {
     919           7 :                                         op2 = Z_REFVAL_P(op2);
     920         236 :                                 } else if (!converted) {
     921         702 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_SUB, sub_function);
     922             : 
     923         671 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     924         672 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     925         229 :                                         converted = 1;
     926             :                                 } else {
     927           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     928           0 :                                         return FAILURE; /* unknown datatype */
     929             :                                 }
     930             :                 }
     931         244 :         }
     932             : }
     933             : /* }}} */
     934             : 
     935         369 : ZEND_API int mul_function(zval *result, zval *op1, zval *op2) /* {{{ */
     936             : {
     937             :         zval op1_copy, op2_copy;
     938         369 :         int converted = 0;
     939             : 
     940             :         while (1) {
     941        1210 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     942             :                         case TYPE_PAIR(IS_LONG, IS_LONG): {
     943             :                                 zend_long overflow;
     944             : 
     945         219 :                                 ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow);
     946         219 :                                 Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
     947         219 :                                 return SUCCESS;
     948             : 
     949             :                         }
     950             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
     951          45 :                                 ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
     952          45 :                                 return SUCCESS;
     953             : 
     954             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
     955          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
     956          61 :                                 return SUCCESS;
     957             : 
     958             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
     959          39 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
     960          39 :                                 return SUCCESS;
     961             : 
     962             :                         default:
     963         241 :                                 if (Z_ISREF_P(op1)) {
     964           4 :                                         op1 = Z_REFVAL_P(op1);
     965         237 :                                 } else if (Z_ISREF_P(op2)) {
     966           4 :                                         op2 = Z_REFVAL_P(op2);
     967         233 :                                 } else if (!converted) {
     968         693 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_MUL, mul_function);
     969             : 
     970         681 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
     971         654 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
     972         228 :                                         converted = 1;
     973             :                                 } else {
     974           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
     975           0 :                                         return FAILURE; /* unknown datatype */
     976             :                                 }
     977             :                 }
     978         236 :         }
     979             : }
     980             : /* }}} */
     981             : 
     982        2229 : ZEND_API int pow_function(zval *result, zval *op1, zval *op2) /* {{{ */
     983             : {
     984             :         zval op1_copy, op2_copy;
     985        2229 :         int converted = 0;
     986             : 
     987             :         while (1) {
     988        4598 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
     989             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
     990        1514 :                                 if (Z_LVAL_P(op2) >= 0) {
     991         831 :                                         zend_long l1 = 1, l2 = Z_LVAL_P(op1), i = Z_LVAL_P(op2);
     992             : 
     993         831 :                                         if (i == 0) {
     994          26 :                                                 ZVAL_LONG(result, 1L);
     995          26 :                                                 return SUCCESS;
     996         805 :                                         } else if (l2 == 0) {
     997          14 :                                                 ZVAL_LONG(result, 0);
     998          14 :                                                 return SUCCESS;
     999             :                                         }
    1000             : 
    1001        6653 :                                         while (i >= 1) {
    1002             :                                                 zend_long overflow;
    1003        5161 :                                                 double dval = 0.0;
    1004             : 
    1005        5161 :                                                 if (i % 2) {
    1006        2004 :                                                         --i;
    1007        2004 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l1, l2, l1, dval, overflow);
    1008        2004 :                                                         if (overflow) {
    1009          17 :                                                                 ZVAL_DOUBLE(result, dval * pow(l2, i));
    1010          17 :                                                                 return SUCCESS;
    1011             :                                                         }
    1012             :                                                 } else {
    1013        3157 :                                                         i /= 2;
    1014        3157 :                                                         ZEND_SIGNED_MULTIPLY_LONG(l2, l2, l2, dval, overflow);
    1015        3157 :                                                         if (overflow) {
    1016          73 :                                                                 ZVAL_DOUBLE(result, (double)l1 * pow(dval, i));
    1017          73 :                                                                 return SUCCESS;
    1018             :                                                         }
    1019             :                                                 }
    1020             :                                         }
    1021             :                                         /* i == 0 */
    1022         701 :                                         ZVAL_LONG(result, l1);
    1023             :                                 } else {
    1024         683 :                                         ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), (double)Z_LVAL_P(op2)));
    1025             :                                 }
    1026        1384 :                                 return SUCCESS;
    1027             : 
    1028             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1029         501 :                                 ZVAL_DOUBLE(result, pow((double)Z_LVAL_P(op1), Z_DVAL_P(op2)));
    1030         501 :                                 return SUCCESS;
    1031             : 
    1032             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1033         144 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), (double)Z_LVAL_P(op2)));
    1034         144 :                                 return SUCCESS;
    1035             : 
    1036             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1037          65 :                                 ZVAL_DOUBLE(result, pow(Z_DVAL_P(op1), Z_DVAL_P(op2)));
    1038          65 :                                 return SUCCESS;
    1039             : 
    1040             :                         default:
    1041          75 :                                 if (Z_ISREF_P(op1)) {
    1042           0 :                                         op1 = Z_REFVAL_P(op1);
    1043          75 :                                 } else if (Z_ISREF_P(op2)) {
    1044           1 :                                         op2 = Z_REFVAL_P(op2);
    1045          74 :                                 } else if (!converted) {
    1046         220 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_POW, pow_function);
    1047             : 
    1048          71 :                                         if (Z_TYPE_P(op1) == IS_ARRAY) {
    1049           1 :                                                 ZVAL_LONG(result, 0);
    1050           1 :                                                 return SUCCESS;
    1051             :                                         } else {
    1052         185 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1053             :                                         }
    1054          70 :                                         if (Z_TYPE_P(op2) == IS_ARRAY) {
    1055           1 :                                                 ZVAL_LONG(result, 1L);
    1056           1 :                                                 return SUCCESS;
    1057             :                                         } else {
    1058         144 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1059             :                                         }
    1060          69 :                                         converted = 1;
    1061             :                                 } else {
    1062           0 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1063           0 :                                         return FAILURE;
    1064             :                                 }
    1065             :                 }
    1066          70 :         }
    1067             : }
    1068             : /* }}} */
    1069             : 
    1070      147082 : ZEND_API int div_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1071             : {
    1072             :         zval op1_copy, op2_copy;
    1073      147082 :         int converted = 0;
    1074             : 
    1075             :         while (1) {
    1076      294582 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1077             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1078      135299 :                                 if (Z_LVAL_P(op2) == 0) {
    1079          43 :                                         zend_error(E_WARNING, "Division by zero");
    1080          43 :                                         ZVAL_FALSE(result);
    1081          43 :                                         return FAILURE;                 /* division by zero */
    1082      135256 :                                 } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN) {
    1083             :                                         /* Prevent overflow error/crash */
    1084           1 :                                         ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
    1085           1 :                                         return SUCCESS;
    1086             :                                 }
    1087      135255 :                                 if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
    1088       83816 :                                         ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
    1089             :                                 } else {
    1090       51439 :                                         ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
    1091             :                                 }
    1092      135255 :                                 return SUCCESS;
    1093             : 
    1094             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1095       11651 :                                 if (Z_LVAL_P(op2) == 0) {
    1096          17 :                                         zend_error(E_WARNING, "Division by zero");
    1097          17 :                                         ZVAL_FALSE(result);
    1098          17 :                                         return FAILURE;                 /* division by zero */
    1099             :                                 }
    1100       11634 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
    1101       11634 :                                 return SUCCESS;
    1102             : 
    1103             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1104          66 :                                 if (Z_DVAL_P(op2) == 0) {
    1105           0 :                                         zend_error(E_WARNING, "Division by zero");
    1106           0 :                                         ZVAL_FALSE(result);
    1107           0 :                                         return FAILURE;                 /* division by zero */
    1108             :                                 }
    1109          66 :                                 ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
    1110          66 :                                 return SUCCESS;
    1111             : 
    1112             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1113          61 :                                 if (Z_DVAL_P(op2) == 0) {
    1114           0 :                                         zend_error(E_WARNING, "Division by zero");
    1115           0 :                                         ZVAL_FALSE(result);
    1116           0 :                                         return FAILURE;                 /* division by zero */
    1117             :                                 }
    1118          61 :                                 ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
    1119          61 :                                 return SUCCESS;
    1120             : 
    1121             :                         default:
    1122         214 :                                 if (Z_ISREF_P(op1)) {
    1123           0 :                                         op1 = Z_REFVAL_P(op1);
    1124         214 :                                 } else if (Z_ISREF_P(op2)) {
    1125           7 :                                         op2 = Z_REFVAL_P(op2);
    1126         207 :                                 } else if (!converted) {
    1127         615 :                                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_DIV, div_function);
    1128             : 
    1129         603 :                                         zendi_convert_scalar_to_number(op1, op1_copy, result);
    1130         601 :                                         zendi_convert_scalar_to_number(op2, op2_copy, result);
    1131         202 :                                         converted = 1;
    1132             :                                 } else {
    1133           1 :                                         zend_error(E_ERROR, "Unsupported operand types");
    1134           0 :                                         return FAILURE; /* unknown datatype */
    1135             :                                 }
    1136             :                 }
    1137         209 :         }
    1138             : }
    1139             : /* }}} */
    1140             : 
    1141         349 : ZEND_API int mod_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1142             : {
    1143             :         zend_long op1_lval, op2_lval;
    1144             : 
    1145        2313 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_MOD, mod_function);
    1146             : 
    1147         345 :         if (op1 == result) {
    1148             :                 zval_dtor(result);
    1149             :         }
    1150             : 
    1151         345 :         if (op2_lval == 0) {
    1152          46 :                 zend_error(E_WARNING, "Division by zero");
    1153          46 :                 ZVAL_FALSE(result);
    1154          46 :                 return FAILURE;                 /* modulus by zero */
    1155             :         }
    1156             : 
    1157         299 :         if (op2_lval == -1) {
    1158             :                 /* Prevent overflow error/crash if op1==LONG_MIN */
    1159           6 :                 ZVAL_LONG(result, 0);
    1160           6 :                 return SUCCESS;
    1161             :         }
    1162             : 
    1163         293 :         ZVAL_LONG(result, op1_lval % op2_lval);
    1164         293 :         return SUCCESS;
    1165             : }
    1166             : /* }}} */
    1167             : 
    1168           2 : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1169             : {
    1170             :         int op1_val, op2_val;
    1171             : 
    1172             :         do {
    1173           2 :                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1174           0 :                         op1_val = 0;
    1175           2 :                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1176           0 :                         op1_val = 1;
    1177             :                 } else {
    1178           2 :                         if (Z_ISREF_P(op1)) {
    1179           0 :                                 op1 = Z_REFVAL_P(op1);
    1180           0 :                                 if (Z_TYPE_P(op1) == IS_FALSE) {
    1181           0 :                                         op1_val = 0;
    1182           0 :                                         break;
    1183           0 :                                 } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1184           0 :                                         op1_val = 1;
    1185           0 :                                         break;
    1186             :                                 }
    1187             :                         }
    1188           4 :                         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BOOL_XOR, boolean_xor_function);
    1189           2 :                         op1_val = zval_is_true(op1);
    1190             :                 }
    1191             :         } while (0);
    1192             :         do {
    1193           2 :                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1194           0 :                         op2_val = 0;
    1195           2 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1196           0 :                         op2_val = 1;
    1197             :                 } else {
    1198           2 :                         if (Z_ISREF_P(op2)) {
    1199           0 :                                 op2 = Z_REFVAL_P(op2);
    1200           0 :                                 if (Z_TYPE_P(op2) == IS_FALSE) {
    1201           0 :                                         op2_val = 0;
    1202           0 :                                         break;
    1203           0 :                                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_TRUE)) {
    1204           0 :                                         op2_val = 1;
    1205           0 :                                         break;
    1206             :                                 }
    1207             :                         }
    1208           2 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BOOL_XOR);
    1209           2 :                         op2_val = zval_is_true(op2);
    1210             :                 }
    1211             :         } while (0);
    1212             : 
    1213           2 :         ZVAL_BOOL(result, op1_val ^ op2_val);
    1214           2 :         return SUCCESS;
    1215             : }
    1216             : /* }}} */
    1217             : 
    1218         174 : ZEND_API int boolean_not_function(zval *result, zval *op1) /* {{{ */
    1219             : {
    1220         174 :         if (Z_TYPE_P(op1) < IS_TRUE) {
    1221           0 :                 ZVAL_TRUE(result);
    1222         174 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1223         173 :                 ZVAL_FALSE(result);
    1224             :         } else {
    1225           1 :                 if (Z_ISREF_P(op1)) {
    1226           0 :                         op1 = Z_REFVAL_P(op1);
    1227           0 :                         if (Z_TYPE_P(op1) < IS_TRUE) {
    1228           0 :                                 ZVAL_TRUE(result);
    1229           0 :                                 return SUCCESS;
    1230           0 :                         } else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
    1231           0 :                                 ZVAL_FALSE(result);
    1232           0 :                                 return SUCCESS;
    1233             :                         }
    1234             :                 }
    1235           1 :                 ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
    1236             : 
    1237           1 :                 ZVAL_BOOL(result, !zval_is_true(op1));
    1238             :         }
    1239         174 :         return SUCCESS;
    1240             : }
    1241             : /* }}} */
    1242             : 
    1243         149 : ZEND_API int bitwise_not_function(zval *result, zval *op1) /* {{{ */
    1244             : {
    1245             : try_again:
    1246         149 :         switch (Z_TYPE_P(op1)) {
    1247             :                 case IS_LONG:
    1248         129 :                         ZVAL_LONG(result, ~Z_LVAL_P(op1));
    1249         129 :                         return SUCCESS;
    1250             :                 case IS_DOUBLE:
    1251           6 :                         ZVAL_LONG(result, ~zend_dval_to_lval(Z_DVAL_P(op1)));
    1252           3 :                         return SUCCESS;
    1253             :                 case IS_STRING: {
    1254             :                         size_t i;
    1255             : 
    1256          30 :                         ZVAL_NEW_STR(result, zend_string_alloc(Z_STRLEN_P(op1), 0));
    1257          83 :                         for (i = 0; i < Z_STRLEN_P(op1); i++) {
    1258          68 :                                 Z_STRVAL_P(result)[i] = ~Z_STRVAL_P(op1)[i];
    1259             :                         }
    1260          15 :                         Z_STRVAL_P(result)[i] = 0;
    1261          15 :                         return SUCCESS;
    1262             :                 }
    1263             :                 case IS_REFERENCE:
    1264           0 :                         op1 = Z_REFVAL_P(op1);
    1265           0 :                         goto try_again;
    1266             :                 default:
    1267           2 :                         ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BW_NOT);
    1268             : 
    1269           1 :                         zend_error(E_ERROR, "Unsupported operand types");
    1270           0 :                         return FAILURE;
    1271             :         }
    1272             : }
    1273             : /* }}} */
    1274             : 
    1275      454348 : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1276             : {
    1277             :         zend_long op1_lval, op2_lval;
    1278             : 
    1279      908473 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1280      454105 :                 ZVAL_LONG(result, Z_LVAL_P(op1) | Z_LVAL_P(op2));
    1281      454105 :                 return SUCCESS;
    1282             :         }
    1283             : 
    1284         243 :         ZVAL_DEREF(op1);
    1285         243 :         ZVAL_DEREF(op2);
    1286             : 
    1287         446 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1288             :                 zval *longer, *shorter;
    1289             :                 zend_string *str;
    1290             :                 size_t i;
    1291             : 
    1292         200 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1293         117 :                         longer = op1;
    1294         117 :                         shorter = op2;
    1295             :                 } else {
    1296          83 :                         longer = op2;
    1297          83 :                         shorter = op1;
    1298             :                 }
    1299             : 
    1300         400 :                 str = zend_string_alloc(Z_STRLEN_P(longer), 0);
    1301         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1302         688 :                         str->val[i] = Z_STRVAL_P(longer)[i] | Z_STRVAL_P(shorter)[i];
    1303             :                 }
    1304         200 :                 memcpy(str->val + i, Z_STRVAL_P(longer) + i, Z_STRLEN_P(longer) - i + 1);
    1305         200 :                 if (result==op1) {
    1306           1 :                         zend_string_release(Z_STR_P(result));
    1307             :                 }
    1308         200 :                 ZVAL_NEW_STR(result, str);
    1309         200 :                 return SUCCESS;
    1310             :         }
    1311             : 
    1312          43 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1313          46 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
    1314          21 :                 op1_lval = _zval_get_long_func(op1);
    1315             :         } else {
    1316          20 :                 op1_lval = Z_LVAL_P(op1);
    1317             :         }
    1318          41 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1319          20 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
    1320          19 :                 op2_lval = _zval_get_long_func(op2);
    1321             :         } else {
    1322          21 :                 op2_lval = Z_LVAL_P(op2);
    1323             :         }
    1324             : 
    1325          40 :         if (op1 == result) {
    1326             :                 zval_dtor(result);
    1327             :         }
    1328          40 :         ZVAL_LONG(result, op1_lval | op2_lval);
    1329          40 :         return SUCCESS;
    1330             : }
    1331             : /* }}} */
    1332             : 
    1333      359543 : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1334             : {
    1335             :         zend_long op1_lval, op2_lval;
    1336             : 
    1337      718850 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1338      359228 :                 ZVAL_LONG(result, Z_LVAL_P(op1) & Z_LVAL_P(op2));
    1339      359228 :                 return SUCCESS;
    1340             :         }
    1341             : 
    1342         315 :         ZVAL_DEREF(op1);
    1343         315 :         ZVAL_DEREF(op2);
    1344             : 
    1345         519 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1346             :                 zval *longer, *shorter;
    1347             :                 zend_string *str;
    1348             :                 size_t i;
    1349             : 
    1350         201 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1351         117 :                         longer = op1;
    1352         117 :                         shorter = op2;
    1353             :                 } else {
    1354          84 :                         longer = op2;
    1355          84 :                         shorter = op1;
    1356             :                 }
    1357             : 
    1358         402 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1359         888 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1360         687 :                         str->val[i] = Z_STRVAL_P(shorter)[i] & Z_STRVAL_P(longer)[i];
    1361             :                 }
    1362         201 :                 str->val[i] = 0;
    1363         201 :                 if (result==op1) {
    1364           1 :                         zend_string_release(Z_STR_P(result));
    1365             :                 }
    1366         201 :                 ZVAL_NEW_STR(result, str);
    1367         201 :                 return SUCCESS;
    1368             :         }
    1369             : 
    1370         114 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1371          70 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_or_function);
    1372          33 :                 op1_lval = _zval_get_long_func(op1);
    1373             :         } else {
    1374          79 :                 op1_lval = Z_LVAL_P(op1);
    1375             :         }
    1376         112 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1377          25 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
    1378          24 :                 op2_lval = _zval_get_long_func(op2);
    1379             :         } else {
    1380          87 :                 op2_lval = Z_LVAL_P(op2);
    1381             :         }
    1382             : 
    1383         111 :         if (op1 == result) {
    1384             :                 zval_dtor(result);
    1385             :         }
    1386         111 :         ZVAL_LONG(result, op1_lval & op2_lval);
    1387         111 :         return SUCCESS;
    1388             : }
    1389             : /* }}} */
    1390             : 
    1391         491 : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1392             : {
    1393             :         zend_long op1_lval, op2_lval;
    1394             : 
    1395         753 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1396         243 :                 ZVAL_LONG(result, Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
    1397         243 :                 return SUCCESS;
    1398             :         }
    1399             : 
    1400         248 :         ZVAL_DEREF(op1);
    1401         248 :         ZVAL_DEREF(op2);
    1402             : 
    1403         453 :         if (Z_TYPE_P(op1) == IS_STRING && Z_TYPE_P(op2) == IS_STRING) {
    1404             :                 zval *longer, *shorter;
    1405             :                 zend_string *str;
    1406             :                 size_t i;
    1407             : 
    1408         202 :                 if (Z_STRLEN_P(op1) >= Z_STRLEN_P(op2)) {
    1409         118 :                         longer = op1;
    1410         118 :                         shorter = op2;
    1411             :                 } else {
    1412          84 :                         longer = op2;
    1413          84 :                         shorter = op1;
    1414             :                 }
    1415             : 
    1416         404 :                 str = zend_string_alloc(Z_STRLEN_P(shorter), 0);
    1417         892 :                 for (i = 0; i < Z_STRLEN_P(shorter); i++) {
    1418         690 :                         str->val[i] = Z_STRVAL_P(shorter)[i] ^ Z_STRVAL_P(longer)[i];
    1419             :                 }
    1420         202 :                 str->val[i] = 0;
    1421         202 :                 if (result==op1) {
    1422           1 :                         zend_string_release(Z_STR_P(result));
    1423             :                 }
    1424         202 :                 ZVAL_NEW_STR(result, str);
    1425         202 :                 return SUCCESS;
    1426             :         }
    1427             : 
    1428          46 :         if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
    1429          54 :                 ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_or_function);
    1430          25 :                 op1_lval = _zval_get_long_func(op1);
    1431             :         } else {
    1432          19 :                 op1_lval = Z_LVAL_P(op1);
    1433             :         }
    1434          44 :         if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
    1435          23 :                 ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
    1436          22 :                 op2_lval = _zval_get_long_func(op2);
    1437             :         } else {
    1438          21 :                 op2_lval = Z_LVAL_P(op2);
    1439             :         }
    1440             : 
    1441          43 :         if (op1 == result) {
    1442             :                 zval_dtor(result);
    1443             :         }
    1444          43 :         ZVAL_LONG(result, op1_lval ^ op2_lval);
    1445          43 :         return SUCCESS;
    1446             : }
    1447             : /* }}} */
    1448             : 
    1449        4436 : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1450             : {
    1451             :         zend_long op1_lval, op2_lval;
    1452             : 
    1453       11986 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SL, shift_left_function);
    1454             : 
    1455        3431 :         if (op1 == result) {
    1456             :                 zval_dtor(result);
    1457             :         }
    1458             : 
    1459             :         /* prevent wrapping quirkiness on some processors where << 64 + x == << x */
    1460        3431 :         if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
    1461         338 :                 if (EXPECTED(op2_lval > 0)) {
    1462         216 :                         ZVAL_LONG(result, 0);
    1463         216 :                         return SUCCESS;
    1464             :                 } else {
    1465         122 :                         zend_error(E_WARNING, "Bit shift by negative number");
    1466         122 :                         ZVAL_FALSE(result);
    1467         122 :                         return FAILURE;
    1468             :                 }
    1469             :         }
    1470             : 
    1471        3093 :         ZVAL_LONG(result, op1_lval << op2_lval);
    1472        3093 :         return SUCCESS;
    1473             : }
    1474             : /* }}} */
    1475             : 
    1476      350248 : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1477             : {
    1478             :         zend_long op1_lval, op2_lval;
    1479             : 
    1480      701606 :         convert_op1_op2_long(op1, op1_lval, op2, op2_lval, ZEND_SR, shift_right_function);
    1481             : 
    1482      350245 :         if (op1 == result) {
    1483             :                 zval_dtor(result);
    1484             :         }
    1485             : 
    1486             :         /* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
    1487      350245 :         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         122 :                         zend_error(E_WARNING, "Bit shift by negative number");
    1493         122 :                         ZVAL_FALSE(result);
    1494         122 :                         return FAILURE;
    1495             :                 }
    1496             :         }
    1497             : 
    1498      349907 :         ZVAL_LONG(result, op1_lval >> op2_lval);
    1499      349907 :         return SUCCESS;
    1500             : }
    1501             : /* }}} */
    1502             : 
    1503             : /* must support result==op1 */
    1504     1104167 : ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1505             : {
    1506     1104167 :         size_t length = Z_STRLEN_P(op1) + 1;
    1507     2208334 :         zend_string *buf = zend_string_realloc(Z_STR_P(op1), length, 0);
    1508             : 
    1509     1104167 :         buf->val[length - 1] = (char) Z_LVAL_P(op2);
    1510     1104167 :         buf->val[length] = 0;
    1511     1104167 :         ZVAL_NEW_STR(result, buf);
    1512     1104167 :         return SUCCESS;
    1513             : }
    1514             : /* }}} */
    1515             : 
    1516             : /* must support result==op1 */
    1517     2940812 : ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2) /* {{{ */
    1518             : {
    1519     2940812 :         size_t op1_len = Z_STRLEN_P(op1);
    1520     2940812 :         size_t length = op1_len + Z_STRLEN_P(op2);
    1521     5881624 :         zend_string *buf = zend_string_realloc(Z_STR_P(op1), length, 0);
    1522             : 
    1523     2940812 :         memcpy(buf->val + op1_len, Z_STRVAL_P(op2), Z_STRLEN_P(op2));
    1524     2940812 :         buf->val[length] = 0;
    1525     2940812 :         ZVAL_NEW_STR(result, buf);
    1526     2940812 :         return SUCCESS;
    1527             : }
    1528             : /* }}} */
    1529             : 
    1530     4572664 : ZEND_API int concat_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1531             : {
    1532             :         zval op1_copy, op2_copy;
    1533     4572664 :         int use_copy1 = 0, use_copy2 = 0;
    1534             : 
    1535             :         do {
    1536     4572664 :                 if (UNEXPECTED(Z_TYPE_P(op1) != IS_STRING)) {
    1537       46490 :                         if (Z_ISREF_P(op1)) {
    1538       15038 :                                 op1 = Z_REFVAL_P(op1);
    1539       15038 :                                 if (Z_TYPE_P(op1) == IS_STRING) break;
    1540             :                         }
    1541       94374 :                         ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
    1542       31459 :                         use_copy1 = zend_make_printable_zval(op1, &op1_copy);
    1543       31459 :                         if (use_copy1) {
    1544             :                                 /* We have created a converted copy of op1. Therefore, op1 won't become the result so
    1545             :                                  * we have to free it.
    1546             :                                  */
    1547       31459 :                                 if (result == op1) {
    1548             :                                         zval_dtor(op1);
    1549           8 :                                         if (UNEXPECTED(op1 == op2)) {
    1550           0 :                                                 op2 = &op1_copy;
    1551             :                                         }
    1552             :                                 }
    1553       31459 :                                 op1 = &op1_copy;
    1554             :                         }
    1555             :                 }
    1556             :         } while (0);
    1557             :         do {
    1558     4572664 :                 if (UNEXPECTED(Z_TYPE_P(op2) != IS_STRING)) {
    1559       24875 :                         if (Z_ISREF_P(op2)) {
    1560         127 :                                 op2 = Z_REFVAL_P(op2);
    1561         127 :                                 if (Z_TYPE_P(op2) == IS_STRING) break;
    1562             :                         }
    1563       24766 :                         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT);
    1564       24766 :                         use_copy2 = zend_make_printable_zval(op2, &op2_copy);
    1565       24766 :                         if (use_copy2) {
    1566       24766 :                                 op2 = &op2_copy;
    1567             :                         }
    1568             :                 }
    1569             :         } while (0);
    1570             : 
    1571             :         {
    1572     4572664 :                 size_t op1_len = Z_STRLEN_P(op1);
    1573     4572664 :                 size_t op2_len = Z_STRLEN_P(op2);
    1574     4572664 :                 size_t result_len = op1_len + op2_len;
    1575             :                 zend_string *result_str;
    1576             : 
    1577     4572664 :                 if (op1_len > SIZE_MAX - op2_len) {
    1578           0 :                         zend_error_noreturn(E_ERROR, "String size overflow");
    1579             :                 }
    1580             : 
    1581     7653712 :                 if (result == op1 && Z_REFCOUNTED_P(result)) {
    1582             :                         /* special case, perform operations on result */
    1583     6162096 :                         result_str = zend_string_realloc(Z_STR_P(result), result_len, 0);
    1584             :                 } else {
    1585     1491616 :                         result_str = zend_string_alloc(result_len, 0);
    1586     1491616 :                         memcpy(result_str->val, Z_STRVAL_P(op1), op1_len);
    1587             :                 }
    1588             : 
    1589             :                 /* This has to happen first to account for the cases where result == op1 == op2 and
    1590             :                  * the realloc is done. In this case this line will also update Z_STRVAL_P(op2) to
    1591             :                  * point to the new string. The first op2_len bytes of result will still be the same. */
    1592     4572664 :                 ZVAL_NEW_STR(result, result_str);
    1593             : 
    1594     4572664 :                 memcpy(result_str->val + op1_len, Z_STRVAL_P(op2), op2_len);
    1595     4572664 :                 result_str->val[result_len] = '\0';
    1596             :         }
    1597             : 
    1598     4572664 :         if (UNEXPECTED(use_copy1)) {
    1599             :                 zval_dtor(op1);
    1600             :         }
    1601     4572664 :         if (UNEXPECTED(use_copy2)) {
    1602             :                 zval_dtor(op2);
    1603             :         }
    1604     4572664 :         return SUCCESS;
    1605             : }
    1606             : /* }}} */
    1607             : 
    1608           0 : ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive) /* {{{ */
    1609             : {
    1610           0 :         zend_string *str1 = zval_get_string(op1);
    1611           0 :         zend_string *str2 = zval_get_string(op2);
    1612             : 
    1613           0 :         if (case_insensitive) {
    1614           0 :                 ZVAL_LONG(result, zend_binary_strcasecmp_l(str1->val, str1->len, str2->val, str1->len));
    1615             :         } else {
    1616           0 :                 ZVAL_LONG(result, zend_binary_strcmp(str1->val, str1->len, str2->val, str2->len));
    1617             :         }
    1618             : 
    1619             :         zend_string_release(str1);
    1620             :         zend_string_release(str2);
    1621           0 :         return SUCCESS;
    1622             : }
    1623             : /* }}} */
    1624             : 
    1625      208945 : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1626             : {
    1627      612304 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1628      202761 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1629      200598 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1630         228 :                         ZVAL_LONG(result, 0);
    1631             :                 } else {
    1632      200370 :                         ZVAL_LONG(result, zend_binary_strcmp(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1633             :                 }
    1634             :         } else {
    1635        8347 :                 zend_string *str1 = zval_get_string(op1);
    1636        8347 :                 zend_string *str2 = zval_get_string(op2);
    1637             : 
    1638        8347 :                 ZVAL_LONG(result, zend_binary_strcmp(str1->val, str1->len, str2->val, str2->len));
    1639             : 
    1640             :                 zend_string_release(str1);
    1641             :                 zend_string_release(str2);
    1642             :         }
    1643      208945 :         return SUCCESS;
    1644             : }
    1645             : /* }}} */
    1646             : 
    1647         125 : ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1648             : {
    1649         341 :         if (EXPECTED(Z_TYPE_P(op1) == IS_STRING) &&
    1650         108 :             EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1651         108 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1652           0 :                         ZVAL_LONG(result, 0);
    1653             :                 } else {
    1654         108 :                         ZVAL_LONG(result, zend_binary_strcasecmp_l(Z_STRVAL_P(op1), Z_STRLEN_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op2)));
    1655             :                 }
    1656             :         } else {
    1657          17 :                 zend_string *str1 = zval_get_string(op1);
    1658          17 :                 zend_string *str2 = zval_get_string(op2);
    1659             : 
    1660          17 :                 ZVAL_LONG(result, zend_binary_strcasecmp_l(str1->val, str1->len, str2->val, str1->len));
    1661             : 
    1662             :                 zend_string_release(str1);
    1663             :                 zend_string_release(str2);
    1664             :         }
    1665         125 :         return SUCCESS;
    1666             : }
    1667             : /* }}} */
    1668             : 
    1669             : #if HAVE_STRCOLL
    1670          29 : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1671             : {
    1672          29 :         zend_string *str1 = zval_get_string(op1);
    1673          29 :         zend_string *str2 = zval_get_string(op2);
    1674             : 
    1675          29 :         ZVAL_LONG(result, strcoll(str1->val, str2->val));
    1676             : 
    1677             :         zend_string_release(str1);
    1678             :         zend_string_release(str2);
    1679          29 :         return SUCCESS;
    1680             : }
    1681             : /* }}} */
    1682             : #endif
    1683             : 
    1684         795 : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1685             : {
    1686             :         double d1, d2;
    1687             : 
    1688         795 :         d1 = zval_get_double(op1);
    1689         795 :         d2 = zval_get_double(op2);
    1690             : 
    1691         795 :         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(d1 - d2));
    1692             : 
    1693         795 :         return SUCCESS;
    1694             : }
    1695             : /* }}} */
    1696             : 
    1697         409 : static inline void zend_free_obj_get_result(zval *op) /* {{{ */
    1698             : {
    1699         409 :         if (Z_REFCOUNTED_P(op)) {
    1700           1 :                 if (Z_REFCOUNT_P(op) == 0) {
    1701             :                         zval_dtor(op);
    1702             :                 } else {
    1703           1 :                         zval_ptr_dtor(op);
    1704             :                 }
    1705             :         }
    1706         409 : }
    1707             : /* }}} */
    1708             : 
    1709      886400 : ZEND_API int compare_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1710             : {
    1711             :         int ret;
    1712      886400 :         int converted = 0;
    1713             :         zval op1_copy, op2_copy;
    1714             :         zval *op_free, tmp_free;
    1715             : 
    1716             :         while (1) {
    1717     2103884 :                 switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
    1718             :                         case TYPE_PAIR(IS_LONG, IS_LONG):
    1719       64755 :                                 ZVAL_LONG(result, Z_LVAL_P(op1)>Z_LVAL_P(op2)?1:(Z_LVAL_P(op1)<Z_LVAL_P(op2)?-1:0));
    1720       64755 :                                 return SUCCESS;
    1721             : 
    1722             :                         case TYPE_PAIR(IS_DOUBLE, IS_LONG):
    1723         422 :                                 Z_DVAL_P(result) = Z_DVAL_P(op1) - (double)Z_LVAL_P(op2);
    1724         422 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1725         422 :                                 return SUCCESS;
    1726             : 
    1727             :                         case TYPE_PAIR(IS_LONG, IS_DOUBLE):
    1728         341 :                                 Z_DVAL_P(result) = (double)Z_LVAL_P(op1) - Z_DVAL_P(op2);
    1729         341 :                                 ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1730         341 :                                 return SUCCESS;
    1731             : 
    1732             :                         case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
    1733         332 :                                 if (Z_DVAL_P(op1) == Z_DVAL_P(op2)) {
    1734          72 :                                         ZVAL_LONG(result, 0);
    1735             :                                 } else {
    1736         260 :                                         Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
    1737         260 :                                         ZVAL_LONG(result, ZEND_NORMALIZE_BOOL(Z_DVAL_P(result)));
    1738             :                                 }
    1739         332 :                                 return SUCCESS;
    1740             : 
    1741             :                         case TYPE_PAIR(IS_ARRAY, IS_ARRAY):
    1742         762 :                                 ZVAL_LONG(result, zend_compare_arrays(op1, op2));
    1743         762 :                                 return SUCCESS;
    1744             : 
    1745             :                         case TYPE_PAIR(IS_NULL, IS_NULL):
    1746             :                         case TYPE_PAIR(IS_NULL, IS_FALSE):
    1747             :                         case TYPE_PAIR(IS_FALSE, IS_NULL):
    1748             :                         case TYPE_PAIR(IS_FALSE, IS_FALSE):
    1749             :                         case TYPE_PAIR(IS_TRUE, IS_TRUE):
    1750        3229 :                                 ZVAL_LONG(result, 0);
    1751        3229 :                                 return SUCCESS;
    1752             : 
    1753             :                         case TYPE_PAIR(IS_NULL, IS_TRUE):
    1754          12 :                                 ZVAL_LONG(result, -1);
    1755          12 :                                 return SUCCESS;
    1756             : 
    1757             :                         case TYPE_PAIR(IS_TRUE, IS_NULL):
    1758          11 :                                 ZVAL_LONG(result, 1);
    1759          11 :                                 return SUCCESS;
    1760             : 
    1761             :                         case TYPE_PAIR(IS_STRING, IS_STRING):
    1762      341560 :                                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1763         199 :                                         ZVAL_LONG(result, 0);
    1764         199 :                                         return SUCCESS;
    1765             :                                 }
    1766      341361 :                                 ZVAL_LONG(result, zendi_smart_strcmp(op1, op2));
    1767      341361 :                                 return SUCCESS;
    1768             : 
    1769             :                         case TYPE_PAIR(IS_NULL, IS_STRING):
    1770       12926 :                                 ZVAL_LONG(result, Z_STRLEN_P(op2) == 0 ? 0 : -1);
    1771       12926 :                                 return SUCCESS;
    1772             : 
    1773             :                         case TYPE_PAIR(IS_STRING, IS_NULL):
    1774         115 :                                 ZVAL_LONG(result, Z_STRLEN_P(op1) == 0 ? 0 : 1);
    1775         115 :                                 return SUCCESS;
    1776             : 
    1777             :                         case TYPE_PAIR(IS_OBJECT, IS_NULL):
    1778          49 :                                 ZVAL_LONG(result, 1);
    1779          49 :                                 return SUCCESS;
    1780             : 
    1781             :                         case TYPE_PAIR(IS_NULL, IS_OBJECT):
    1782          15 :                                 ZVAL_LONG(result, -1);
    1783          15 :                                 return SUCCESS;
    1784             : 
    1785             :                         default:
    1786      627413 :                                 if (Z_ISREF_P(op1)) {
    1787      109044 :                                         op1 = Z_REFVAL_P(op1);
    1788      109044 :                                         continue;
    1789      518369 :                                 } else if (Z_ISREF_P(op2)) {
    1790       24622 :                                         op2 = Z_REFVAL_P(op2);
    1791       24622 :                                         continue;
    1792             :                                 }
    1793             : 
    1794      493747 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_OBJ_HANDLER_P(op1, compare)) {
    1795       55018 :                                         return Z_OBJ_HANDLER_P(op1, compare)(result, op1, op2);
    1796      438729 :                                 } else if (Z_TYPE_P(op2) == IS_OBJECT && Z_OBJ_HANDLER_P(op2, compare)) {
    1797       55004 :                                         return Z_OBJ_HANDLER_P(op2, compare)(result, op1, op2);
    1798             :                                 }
    1799             : 
    1800      730786 :                                 if (Z_TYPE_P(op1) == IS_OBJECT && Z_TYPE_P(op2) == IS_OBJECT) {
    1801      346849 :                                         if (Z_OBJ_P(op1) == Z_OBJ_P(op2)) {
    1802             :                                                 /* object handles are identical, apparently this is the same object */
    1803          24 :                                                 ZVAL_LONG(result, 0);
    1804          24 :                                                 return SUCCESS;
    1805             :                                         }
    1806      346825 :                                         if (Z_OBJ_HANDLER_P(op1, compare_objects) == Z_OBJ_HANDLER_P(op2, compare_objects)) {
    1807      346824 :                                                 ZVAL_LONG(result, Z_OBJ_HANDLER_P(op1, compare_objects)(op1, op2));
    1808      346820 :                                                 return SUCCESS;
    1809             :                                         }
    1810             :                                 }
    1811       36877 :                                 if (Z_TYPE_P(op1) == IS_OBJECT) {
    1812         213 :                                         if (Z_OBJ_HT_P(op1)->get) {
    1813             :                                                 zval rv;
    1814           1 :                                                 op_free = Z_OBJ_HT_P(op1)->get(op1, &rv);
    1815           1 :                                                 ret = compare_function(result, op_free, op2);
    1816           1 :                                                 zend_free_obj_get_result(op_free);
    1817           1 :                                                 return ret;
    1818         212 :                                         } else if (Z_TYPE_P(op2) != IS_OBJECT && Z_OBJ_HT_P(op1)->cast_object) {
    1819         211 :                                                 ZVAL_UNDEF(&tmp_free);
    1820         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) {
    1821         112 :                                                         ZVAL_LONG(result, 1);
    1822         112 :                                                         zend_free_obj_get_result(&tmp_free);
    1823         112 :                                                         return SUCCESS;
    1824             :                                                 }
    1825          99 :                                                 ret = compare_function(result, &tmp_free, op2);
    1826          99 :                                                 zend_free_obj_get_result(&tmp_free);
    1827          99 :                                                 return ret;
    1828             :                                         }
    1829             :                                 }
    1830       36665 :                                 if (Z_TYPE_P(op2) == IS_OBJECT) {
    1831         198 :                                         if (Z_OBJ_HT_P(op2)->get) {
    1832             :                                                 zval rv;
    1833           0 :                                                 op_free = Z_OBJ_HT_P(op2)->get(op2, &rv);
    1834           0 :                                                 ret = compare_function(result, op1, op_free);
    1835           0 :                                                 zend_free_obj_get_result(op_free);
    1836           0 :                                                 return ret;
    1837         198 :                                         } else if (Z_TYPE_P(op1) != IS_OBJECT && Z_OBJ_HT_P(op2)->cast_object) {
    1838         197 :                                                 ZVAL_UNDEF(&tmp_free);
    1839         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) {
    1840         107 :                                                         ZVAL_LONG(result, -1);
    1841         107 :                                                         zend_free_obj_get_result(&tmp_free);
    1842         107 :                                                         return SUCCESS;
    1843             :                                                 }
    1844          90 :                                                 ret = compare_function(result, op1, &tmp_free);
    1845          90 :                                                 zend_free_obj_get_result(&tmp_free);
    1846          90 :                                                 return ret;
    1847           1 :                                         } else if (Z_TYPE_P(op1) == IS_OBJECT) {
    1848           1 :                                                 ZVAL_LONG(result, 1);
    1849           1 :                                                 return SUCCESS;
    1850             :                                         }
    1851             :                                 }
    1852       36467 :                                 if (!converted) {
    1853       71636 :                                         if (Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op1) == IS_FALSE) {
    1854        2336 :                                                 ZVAL_LONG(result, zval_is_true(op2) ? -1 : 0);
    1855        2336 :                                                 return SUCCESS;
    1856       67071 :                                         } else if (Z_TYPE_P(op2) == IS_NULL || Z_TYPE_P(op2) == IS_FALSE) {
    1857        1335 :                                                 ZVAL_LONG(result, zval_is_true(op1) ? 1 : 0);
    1858        1335 :                                                 return SUCCESS;
    1859       32244 :                                         } else if (Z_TYPE_P(op1) == IS_TRUE) {
    1860         194 :                                                 ZVAL_LONG(result, zval_is_true(op2) ? 0 : 1);
    1861         194 :                                                 return SUCCESS;
    1862       32050 :                                         } else if (Z_TYPE_P(op2) == IS_TRUE) {
    1863         174 :                                                 ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
    1864         174 :                                                 return SUCCESS;
    1865             :                                         } else {
    1866       80034 :                                                 zendi_convert_scalar_to_number(op1, op1_copy, result);
    1867       79069 :                                                 zendi_convert_scalar_to_number(op2, op2_copy, result);
    1868       31876 :                                                 converted = 1;
    1869             :                                         }
    1870         552 :                                 } else if (Z_TYPE_P(op1)==IS_ARRAY) {
    1871         293 :                                         ZVAL_LONG(result, 1);
    1872         293 :                                         return SUCCESS;
    1873         259 :                                 } else if (Z_TYPE_P(op2)==IS_ARRAY) {
    1874         259 :                                         ZVAL_LONG(result, -1);
    1875         259 :                                         return SUCCESS;
    1876           0 :                                 } else if (Z_TYPE_P(op1)==IS_OBJECT) {
    1877           0 :                                         ZVAL_LONG(result, 1);
    1878           0 :                                         return SUCCESS;
    1879           0 :                                 } else if (Z_TYPE_P(op2)==IS_OBJECT) {
    1880           0 :                                         ZVAL_LONG(result, -1);
    1881           0 :                                         return SUCCESS;
    1882             :                                 } else {
    1883           0 :                                         ZVAL_LONG(result, 0);
    1884           0 :                                         return FAILURE;
    1885             :                                 }
    1886             :                 }
    1887      165542 :         }
    1888             : }
    1889             : /* }}} */
    1890             : 
    1891        1138 : static int hash_zval_identical_function(zval *z1, zval *z2) /* {{{ */
    1892             : {
    1893             :         zval result;
    1894             : 
    1895             :         /* is_identical_function() returns 1 in case of identity and 0 in case
    1896             :          * of a difference;
    1897             :          * whereas this comparison function is expected to return 0 on identity,
    1898             :          * and non zero otherwise.
    1899             :          */
    1900        1138 :         ZVAL_DEREF(z1);
    1901        1138 :         ZVAL_DEREF(z2);
    1902        1138 :         if (is_identical_function(&result, z1, z2)==FAILURE) {
    1903           0 :                 return 1;
    1904             :         }
    1905        1138 :         return Z_TYPE(result) != IS_TRUE;
    1906             : }
    1907             : /* }}} */
    1908             : 
    1909     1077421 : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1910             : {
    1911     1077421 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    1912           8 :                 ZVAL_FALSE(result);
    1913           8 :                 return SUCCESS;
    1914             :         }
    1915     1077413 :         switch (Z_TYPE_P(op1)) {
    1916             :                 case IS_NULL:
    1917             :                 case IS_FALSE:
    1918             :                 case IS_TRUE:
    1919       53387 :                         ZVAL_TRUE(result);
    1920       53387 :                         break;
    1921             :                 case IS_LONG:
    1922      915395 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) == Z_LVAL_P(op2));
    1923      915395 :                         break;
    1924             :                 case IS_RESOURCE:
    1925          10 :                         ZVAL_BOOL(result, Z_RES_P(op1) == Z_RES_P(op2));
    1926          10 :                         break;
    1927             :                 case IS_DOUBLE:
    1928         179 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) == Z_DVAL_P(op2));
    1929         179 :                         break;
    1930             :                 case IS_STRING:
    1931       42283 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1932       26080 :                                 ZVAL_TRUE(result);
    1933             :                         } else {
    1934       16203 :                                 ZVAL_BOOL(result, (Z_STRLEN_P(op1) == Z_STRLEN_P(op2))
    1935             :                                         && (!memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1))));
    1936             :                         }
    1937       42283 :                         break;
    1938             :                 case IS_ARRAY:
    1939          72 :                         ZVAL_BOOL(result, Z_ARRVAL_P(op1) == Z_ARRVAL_P(op2) ||
    1940             :                                 zend_hash_compare(Z_ARRVAL_P(op1), Z_ARRVAL_P(op2), (compare_func_t) hash_zval_identical_function, 1)==0);
    1941          72 :                         break;
    1942             :                 case IS_OBJECT:
    1943       66087 :                         if (Z_OBJ_HT_P(op1) == Z_OBJ_HT_P(op2)) {
    1944       66087 :                                 ZVAL_BOOL(result, Z_OBJ_P(op1) == Z_OBJ_P(op2));
    1945             :                         } else {
    1946           0 :                                 ZVAL_FALSE(result);
    1947             :                         }
    1948       66087 :                         break;
    1949             :                 default:
    1950           0 :                         ZVAL_FALSE(result);
    1951           0 :                         return FAILURE;
    1952             :         }
    1953     1077413 :         return SUCCESS;
    1954             : }
    1955             : /* }}} */
    1956             : 
    1957          18 : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1958             : {
    1959          18 :         if (is_identical_function(result, op1, op2) == FAILURE) {
    1960           0 :                 return FAILURE;
    1961             :         }
    1962          18 :         ZVAL_BOOL(result, Z_TYPE_P(result) != IS_TRUE);
    1963          18 :         return SUCCESS;
    1964             : }
    1965             : /* }}} */
    1966             : 
    1967          68 : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1968             : {
    1969          68 :         if (compare_function(result, op1, op2) == FAILURE) {
    1970           0 :                 return FAILURE;
    1971             :         }
    1972          68 :         ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
    1973          68 :         return SUCCESS;
    1974             : }
    1975             : /* }}} */
    1976             : 
    1977         385 : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1978             : {
    1979         385 :         if (compare_function(result, op1, op2) == FAILURE) {
    1980           0 :                 return FAILURE;
    1981             :         }
    1982         385 :         ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
    1983         385 :         return SUCCESS;
    1984             : }
    1985             : /* }}} */
    1986             : 
    1987        1948 : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1988             : {
    1989        1948 :         if (compare_function(result, op1, op2) == FAILURE) {
    1990           0 :                 return FAILURE;
    1991             :         }
    1992        1948 :         ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
    1993        1948 :         return SUCCESS;
    1994             : }
    1995             : /* }}} */
    1996             : 
    1997        1286 : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2) /* {{{ */
    1998             : {
    1999        1286 :         if (compare_function(result, op1, op2) == FAILURE) {
    2000           0 :                 return FAILURE;
    2001             :         }
    2002        1286 :         ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
    2003        1286 :         return SUCCESS;
    2004             : }
    2005             : /* }}} */
    2006             : 
    2007           0 : static zend_bool instanceof_interface_only(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2008             : {
    2009             :         uint32_t i;
    2010             : 
    2011           0 :         for (i = 0; i < instance_ce->num_interfaces; i++) {
    2012           0 :                 if (instanceof_interface_only(instance_ce->interfaces[i], ce)) {
    2013           0 :                         return 1;
    2014             :                 }
    2015             :         }
    2016           0 :         return 0;
    2017             : }
    2018             : /* }}} */
    2019             : 
    2020             : static zend_always_inline zend_bool instanceof_class(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2021             : {
    2022     2164406 :         while (instance_ce) {
    2023     1750620 :                 if (instance_ce == ce) {
    2024     1327025 :                         return 1;
    2025             :                 }
    2026      423595 :                 instance_ce = instance_ce->parent;
    2027             :         }
    2028      413786 :         return 0;
    2029             : }
    2030             : /* }}} */
    2031             : 
    2032     1241018 : static zend_bool instanceof_interface(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2033             : {
    2034             :         uint32_t i;
    2035             : 
    2036     1642661 :         for (i = 0; i < instance_ce->num_interfaces; i++) {
    2037      821466 :                 if (instanceof_interface(instance_ce->interfaces[i], ce)) {
    2038      419823 :                         return 1;
    2039             :                 }
    2040             :         }
    2041      821195 :         return instanceof_class(instance_ce, ce);
    2042             : }
    2043             : /* }}} */
    2044             : 
    2045       65370 : ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only) /* {{{ */
    2046             : {
    2047       65370 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    2048       65363 :                 if (!interfaces_only) {
    2049           0 :                         if (instanceof_interface_only(instance_ce, ce)) {
    2050           0 :                                 return 1;
    2051             :                         }
    2052             :                 } else {
    2053       65363 :                         return instanceof_interface(instance_ce, ce);
    2054             :                 }
    2055             :         }
    2056           7 :         if (!interfaces_only) {
    2057           7 :                 return instanceof_class(instance_ce, ce);
    2058             :         }
    2059           0 :         return 0;
    2060             : }
    2061             : /* }}} */
    2062             : 
    2063     1273798 : ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce) /* {{{ */
    2064             : {
    2065     1273798 :         if (ce->ce_flags & ZEND_ACC_INTERFACE) {
    2066      354189 :                 return instanceof_interface(instance_ce, ce);
    2067             :         } else {
    2068      919609 :                 return instanceof_class(instance_ce, ce);
    2069             :         }
    2070             : }
    2071             : /* }}} */
    2072             : 
    2073             : #define LOWER_CASE 1
    2074             : #define UPPER_CASE 2
    2075             : #define NUMERIC 3
    2076             : 
    2077          55 : static void increment_string(zval *str) /* {{{ */
    2078             : {
    2079          55 :         int carry=0;
    2080          55 :         size_t pos=Z_STRLEN_P(str)-1;
    2081             :         char *s;
    2082             :         zend_string *t;
    2083          55 :         int last=0; /* Shut up the compiler warning */
    2084             :         int ch;
    2085             : 
    2086          55 :         if (Z_STRLEN_P(str) == 0) {
    2087           0 :                 zend_string_release(Z_STR_P(str));
    2088           0 :                 Z_STR_P(str) = zend_string_init("1", sizeof("1")-1, 0);
    2089           0 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2090           0 :                 return;
    2091             :         }
    2092             : 
    2093          55 :         if (!Z_REFCOUNTED_P(str)) {
    2094          10 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2095           5 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    2096          50 :         } else if (Z_REFCOUNT_P(str) > 1) {
    2097             :                 Z_DELREF_P(str);
    2098           0 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    2099             :         } else {
    2100          50 :                 zend_string_forget_hash_val(Z_STR_P(str));
    2101             :         }
    2102          55 :         s = Z_STRVAL_P(str);
    2103             : 
    2104             :         do {
    2105          68 :                 ch = s[pos];
    2106         107 :                 if (ch >= 'a' && ch <= 'z') {
    2107          39 :                         if (ch == 'z') {
    2108           9 :                                 s[pos] = 'a';
    2109           9 :                                 carry=1;
    2110             :                         } else {
    2111          30 :                                 s[pos]++;
    2112          30 :                                 carry=0;
    2113             :                         }
    2114          39 :                         last=LOWER_CASE;
    2115          40 :                 } else if (ch >= 'A' && ch <= 'Z') {
    2116          11 :                         if (ch == 'Z') {
    2117           4 :                                 s[pos] = 'A';
    2118           4 :                                 carry=1;
    2119             :                         } else {
    2120           7 :                                 s[pos]++;
    2121           7 :                                 carry=0;
    2122             :                         }
    2123          11 :                         last=UPPER_CASE;
    2124          32 :                 } else if (ch >= '0' && ch <= '9') {
    2125          14 :                         if (ch == '9') {
    2126           6 :                                 s[pos] = '0';
    2127           6 :                                 carry=1;
    2128             :                         } else {
    2129           8 :                                 s[pos]++;
    2130           8 :                                 carry=0;
    2131             :                         }
    2132          14 :                         last = NUMERIC;
    2133             :                 } else {
    2134           4 :                         carry=0;
    2135           4 :                         break;
    2136             :                 }
    2137          64 :                 if (carry == 0) {
    2138          45 :                         break;
    2139             :                 }
    2140          19 :         } while (pos-- > 0);
    2141             : 
    2142          55 :         if (carry) {
    2143          12 :                 t = zend_string_alloc(Z_STRLEN_P(str)+1, 0);
    2144           6 :                 memcpy(t->val + 1, Z_STRVAL_P(str), Z_STRLEN_P(str));
    2145           6 :                 t->val[Z_STRLEN_P(str) + 1] = '\0';
    2146           6 :                 switch (last) {
    2147             :                         case NUMERIC:
    2148           2 :                                 t->val[0] = '1';
    2149           2 :                                 break;
    2150             :                         case UPPER_CASE:
    2151           2 :                                 t->val[0] = 'A';
    2152           2 :                                 break;
    2153             :                         case LOWER_CASE:
    2154           2 :                                 t->val[0] = 'a';
    2155             :                                 break;
    2156             :                 }
    2157           6 :                 zend_string_free(Z_STR_P(str));
    2158           6 :                 ZVAL_NEW_STR(str, t);
    2159             :         }
    2160             : }
    2161             : /* }}} */
    2162             : 
    2163       18407 : ZEND_API int increment_function(zval *op1) /* {{{ */
    2164             : {
    2165             : try_again:
    2166       18407 :         switch (Z_TYPE_P(op1)) {
    2167             :                 case IS_LONG:
    2168       18304 :                         if (Z_LVAL_P(op1) == ZEND_LONG_MAX) {
    2169             :                                 /* switch to double */
    2170           0 :                                 double d = (double)Z_LVAL_P(op1);
    2171           0 :                                 ZVAL_DOUBLE(op1, d+1);
    2172             :                         } else {
    2173       18304 :                         Z_LVAL_P(op1)++;
    2174             :                         }
    2175       18304 :                         break;
    2176             :                 case IS_DOUBLE:
    2177           4 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
    2178           4 :                         break;
    2179             :                 case IS_NULL:
    2180          27 :                         ZVAL_LONG(op1, 1);
    2181          27 :                         break;
    2182             :                 case IS_STRING: {
    2183             :                                 zend_long lval;
    2184             :                                 double dval;
    2185             : 
    2186         138 :                                 switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2187             :                                         case IS_LONG:
    2188           8 :                                                 zend_string_release(Z_STR_P(op1));
    2189           8 :                                                 if (lval == ZEND_LONG_MAX) {
    2190             :                                                         /* switch to double */
    2191           0 :                                                         double d = (double)lval;
    2192           0 :                                                         ZVAL_DOUBLE(op1, d+1);
    2193             :                                                 } else {
    2194           8 :                                                         ZVAL_LONG(op1, lval+1);
    2195             :                                                 }
    2196           8 :                                                 break;
    2197             :                                         case IS_DOUBLE:
    2198           6 :                                                 zend_string_release(Z_STR_P(op1));
    2199           6 :                                                 ZVAL_DOUBLE(op1, dval+1);
    2200           6 :                                                 break;
    2201             :                                         default:
    2202             :                                                 /* Perl style string increment */
    2203          55 :                                                 increment_string(op1);
    2204             :                                                 break;
    2205             :                                 }
    2206             :                         }
    2207          69 :                         break;
    2208             :                 case IS_OBJECT:
    2209           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2210           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2211             :                                 /* proxy object */
    2212             :                                 zval rv;
    2213             :                                 zval *val;
    2214             : 
    2215           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
    2216             :                                 Z_ADDREF_P(val);
    2217             :                                 fast_increment_function(val);
    2218           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val);
    2219           0 :                                 zval_ptr_dtor(val);
    2220           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2221             :                                 zval op2;
    2222             :                                 int res;
    2223             : 
    2224           2 :                                 ZVAL_LONG(&op2, 1);
    2225           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_ADD, op1, op1, &op2);
    2226           2 :                                 zval_ptr_dtor(&op2);
    2227             : 
    2228           2 :                                 return res;
    2229             :                         }
    2230           1 :                         return FAILURE;
    2231             :                 case IS_REFERENCE:
    2232           0 :                         op1 = Z_REFVAL_P(op1);
    2233           0 :                         goto try_again;
    2234             :                 default:
    2235           0 :                         return FAILURE;
    2236             :         }
    2237       18404 :         return SUCCESS;
    2238             : }
    2239             : /* }}} */
    2240             : 
    2241      294364 : ZEND_API int decrement_function(zval *op1) /* {{{ */
    2242             : {
    2243             :         zend_long lval;
    2244             :         double dval;
    2245             : 
    2246             : try_again:
    2247      294364 :         switch (Z_TYPE_P(op1)) {
    2248             :                 case IS_LONG:
    2249          18 :                         if (Z_LVAL_P(op1) == ZEND_LONG_MIN) {
    2250           0 :                                 double d = (double)Z_LVAL_P(op1);
    2251           0 :                                 ZVAL_DOUBLE(op1, d-1);
    2252             :                         } else {
    2253          18 :                         Z_LVAL_P(op1)--;
    2254             :                         }
    2255          18 :                         break;
    2256             :                 case IS_DOUBLE:
    2257      294305 :                         Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
    2258      294305 :                         break;
    2259             :                 case IS_STRING:         /* Like perl we only support string increment */
    2260          33 :                         if (Z_STRLEN_P(op1) == 0) { /* consider as 0 */
    2261           1 :                                 zend_string_release(Z_STR_P(op1));
    2262           1 :                                 ZVAL_LONG(op1, -1);
    2263           1 :                                 break;
    2264             :                         }
    2265          64 :                         switch (is_numeric_string(Z_STRVAL_P(op1), Z_STRLEN_P(op1), &lval, &dval, 0)) {
    2266             :                                 case IS_LONG:
    2267           8 :                                         zend_string_release(Z_STR_P(op1));
    2268           8 :                                         if (lval == ZEND_LONG_MIN) {
    2269           1 :                                                 double d = (double)lval;
    2270           1 :                                                 ZVAL_DOUBLE(op1, d-1);
    2271             :                                         } else {
    2272           7 :                                                 ZVAL_LONG(op1, lval-1);
    2273             :                                         }
    2274           8 :                                         break;
    2275             :                                 case IS_DOUBLE:
    2276           7 :                                         zend_string_release(Z_STR_P(op1));
    2277           7 :                                         ZVAL_DOUBLE(op1, dval - 1);
    2278             :                                         break;
    2279             :                         }
    2280          32 :                         break;
    2281             :                 case IS_OBJECT:
    2282           6 :                         if (Z_OBJ_HANDLER_P(op1, get)
    2283           3 :                            && Z_OBJ_HANDLER_P(op1, set)) {
    2284             :                                 /* proxy object */
    2285             :                                 zval rv;
    2286             :                                 zval *val;
    2287             : 
    2288           0 :                                 val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
    2289             :                                 Z_ADDREF_P(val);
    2290             :                                 fast_decrement_function(val);
    2291           0 :                                 Z_OBJ_HANDLER_P(op1, set)(op1, val);
    2292           0 :                                 zval_ptr_dtor(val);
    2293           3 :                         } else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
    2294             :                                 zval op2;
    2295             :                                 int res;
    2296             : 
    2297           2 :                                 ZVAL_LONG(&op2, 1);
    2298           2 :                                 res = Z_OBJ_HANDLER_P(op1, do_operation)(ZEND_SUB, op1, op1, &op2);
    2299           2 :                                 zval_ptr_dtor(&op2);
    2300             : 
    2301           2 :                                 return res;
    2302             :                         }
    2303           1 :                         return FAILURE;
    2304             :                 case IS_REFERENCE:
    2305           0 :                         op1 = Z_REFVAL_P(op1);
    2306           0 :                         goto try_again;
    2307             :                 default:
    2308           5 :                         return FAILURE;
    2309             :         }
    2310             : 
    2311      294356 :         return SUCCESS;
    2312             : }
    2313             : /* }}} */
    2314             : 
    2315       18875 : ZEND_API int zend_is_true(zval *op) /* {{{ */
    2316             : {
    2317       18874 :         return i_zend_is_true(op);
    2318             : }
    2319             : /* }}} */
    2320             : 
    2321       92373 : ZEND_API int zend_object_is_true(zval *op) /* {{{ */
    2322             : {
    2323       92373 :         if (Z_OBJ_HT_P(op)->cast_object) {
    2324             :                 zval tmp;
    2325       92373 :                 if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL) == SUCCESS) {
    2326       92372 :                         return Z_TYPE(tmp) == IS_TRUE;
    2327             :                 }
    2328           1 :                 zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", Z_OBJ_P(op)->ce->name->val);
    2329           0 :         } else if (Z_OBJ_HT_P(op)->get) {
    2330             :                 int result;
    2331             :                 zval rv;
    2332           0 :                 zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv);
    2333             : 
    2334           0 :                 if (Z_TYPE_P(tmp) != IS_OBJECT) {
    2335             :                         /* for safety - avoid loop */
    2336           0 :                         result = i_zend_is_true(tmp);
    2337           0 :                         zval_ptr_dtor(tmp);
    2338           0 :                         return result;
    2339             :                 }
    2340             :         }
    2341           0 :         return 1;
    2342             : }
    2343             : /* }}} */
    2344             : 
    2345             : #ifdef ZEND_USE_TOLOWER_L
    2346             : ZEND_API void zend_update_current_locale(void) /* {{{ */
    2347             : {
    2348             :         current_locale = _get_current_locale();
    2349             : }
    2350             : /* }}} */
    2351             : #endif
    2352             : 
    2353   139835477 : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, size_t length) /* {{{ */
    2354             : {
    2355   139835477 :         register unsigned char *str = (unsigned char*)source;
    2356   139835477 :         register unsigned char *result = (unsigned char*)dest;
    2357   139835477 :         register unsigned char *end = str + length;
    2358             : 
    2359  2149433419 :         while (str < end) {
    2360  1869762465 :                 *result++ = zend_tolower_ascii(*str++);
    2361             :         }
    2362   139835477 :         *result = '\0';
    2363             : 
    2364   139835477 :         return dest;
    2365             : }
    2366             : /* }}} */
    2367             : 
    2368     4219888 : ZEND_API char *zend_str_tolower_dup(const char *source, size_t length) /* {{{ */
    2369             : {
    2370     4219888 :         return zend_str_tolower_copy((char *)emalloc(length+1), source, length);
    2371             : }
    2372             : /* }}} */
    2373             : 
    2374       61251 : ZEND_API void zend_str_tolower(char *str, size_t length) /* {{{ */
    2375             : {
    2376       61251 :         register unsigned char *p = (unsigned char*)str;
    2377       61251 :         register unsigned char *end = p + length;
    2378             : 
    2379      548042 :         while (p < end) {
    2380      425540 :                 *p = zend_tolower_ascii(*p);
    2381      425540 :                 p++;
    2382             :         }
    2383       61251 : }
    2384             : /* }}} */
    2385             : 
    2386     1031923 : ZEND_API zend_string *zend_string_tolower(zend_string *str) /* {{{ */
    2387             : {
    2388     1031923 :         register unsigned char *p = (unsigned char*)str->val;
    2389     1031923 :         register unsigned char *end = p + str->len;
    2390             : 
    2391    37137404 :         while (p < end) {
    2392    35739715 :                 if (*p != zend_tolower_ascii(*p)) {
    2393     1332314 :                         zend_string *res = zend_string_alloc(str->len, 0);
    2394             :                         register unsigned char *r;
    2395             : 
    2396      666157 :                         if (p != (unsigned char*)str->val) {
    2397       33437 :                                 memcpy(res->val, str->val, p - (unsigned char*)str->val);
    2398             :                         }
    2399      666157 :                         r = p + (res->val - str->val);
    2400     6456756 :                         while (p < end) {
    2401     5124442 :                                 *r = zend_tolower_ascii(*p);
    2402     5124442 :                                 p++;
    2403     5124442 :                                 r++;
    2404             :                         }
    2405      666157 :                         *r = '\0';
    2406      666157 :                         return res;
    2407             :                 }
    2408    35073558 :                 p++;
    2409             :         }
    2410      365766 :         return zend_string_copy(str);
    2411             : }
    2412             : /* }}} */
    2413             : 
    2414      808272 : ZEND_API int zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2415             : {
    2416             :         int retval;
    2417             : 
    2418      808272 :         if (s1 == s2) {
    2419         298 :                 return 0;
    2420             :         }
    2421      807974 :         retval = memcmp(s1, s2, MIN(len1, len2));
    2422      807974 :         if (!retval) {
    2423      227684 :                 return (int)(len1 - len2);
    2424             :         } else {
    2425      580290 :                 return retval;
    2426             :         }
    2427             : }
    2428             : /* }}} */
    2429             : 
    2430       14361 : ZEND_API int zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2431             : {
    2432             :         int retval;
    2433             : 
    2434       14361 :         if (s1 == s2) {
    2435          44 :                 return 0;
    2436             :         }
    2437       14317 :         retval = memcmp(s1, s2, MIN(length, MIN(len1, len2)));
    2438       14317 :         if (!retval) {
    2439       14041 :                 return (int)(MIN(length, len1) - MIN(length, len2));
    2440             :         } else {
    2441         276 :                 return retval;
    2442             :         }
    2443             : }
    2444             : /* }}} */
    2445             : 
    2446      361269 : ZEND_API int zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2447             : {
    2448             :         size_t len;
    2449             :         int c1, c2;
    2450             : 
    2451      361269 :         if (s1 == s2) {
    2452         121 :                 return 0;
    2453             :         }
    2454             : 
    2455      361148 :         len = MIN(len1, len2);
    2456     1405982 :         while (len--) {
    2457     1030921 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2458     1030921 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2459     1030921 :                 if (c1 != c2) {
    2460      347235 :                         return c1 - c2;
    2461             :                 }
    2462             :         }
    2463             : 
    2464       13913 :         return (int)(len1 - len2);
    2465             : }
    2466             : /* }}} */
    2467             : 
    2468       20263 : ZEND_API int zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2469             : {
    2470             :         size_t len;
    2471             :         int c1, c2;
    2472             : 
    2473       20263 :         if (s1 == s2) {
    2474          45 :                 return 0;
    2475             :         }
    2476       20218 :         len = MIN(length, MIN(len1, len2));
    2477       47663 :         while (len--) {
    2478        7685 :                 c1 = zend_tolower_ascii(*(unsigned char *)s1++);
    2479        7685 :                 c2 = zend_tolower_ascii(*(unsigned char *)s2++);
    2480        7685 :                 if (c1 != c2) {
    2481         458 :                         return c1 - c2;
    2482             :                 }
    2483             :         }
    2484             : 
    2485       19760 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2486             : }
    2487             : /* }}} */
    2488             : 
    2489         125 : ZEND_API int zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2) /* {{{ */
    2490             : {
    2491             :         size_t len;
    2492             :         int c1, c2;
    2493             : 
    2494         125 :         if (s1 == s2) {
    2495           0 :                 return 0;
    2496             :         }
    2497             : 
    2498         125 :         len = MIN(len1, len2);
    2499         569 :         while (len--) {
    2500         407 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2501         407 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2502         407 :                 if (c1 != c2) {
    2503          88 :                         return c1 - c2;
    2504             :                 }
    2505             :         }
    2506             : 
    2507          37 :         return (int)(len1 - len2);
    2508             : }
    2509             : /* }}} */
    2510             : 
    2511           1 : ZEND_API int zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length) /* {{{ */
    2512             : {
    2513             :         size_t len;
    2514             :         int c1, c2;
    2515             : 
    2516           1 :         if (s1 == s2) {
    2517           0 :                 return 0;
    2518             :         }
    2519           1 :         len = MIN(length, MIN(len1, len2));
    2520           4 :         while (len--) {
    2521           2 :                 c1 = zend_tolower((int)*(unsigned char *)s1++);
    2522           2 :                 c2 = zend_tolower((int)*(unsigned char *)s2++);
    2523           2 :                 if (c1 != c2) {
    2524           0 :                         return c1 - c2;
    2525             :                 }
    2526             :         }
    2527             : 
    2528           1 :         return (int)(MIN(length, len1) - MIN(length, len2));
    2529             : }
    2530             : /* }}} */
    2531             : 
    2532           2 : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2) /* {{{ */
    2533             : {
    2534           2 :         return zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2535             : }
    2536             : /* }}} */
    2537             : 
    2538           0 : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2539             : {
    2540           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));
    2541             : }
    2542             : /* }}} */
    2543             : 
    2544           0 : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
    2545             : {
    2546           0 :         return zend_binary_strcasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2547             : }
    2548             : /* }}} */
    2549             : 
    2550           0 : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
    2551             : {
    2552           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));
    2553             : }
    2554             : /* }}} */
    2555             : 
    2556      631445 : ZEND_API zend_long zendi_smart_strcmp(zval *s1, zval *s2) /* {{{ */
    2557             : {
    2558             :         int ret1, ret2;
    2559             :         int oflow1, oflow2;
    2560      631445 :         zend_long lval1 = 0, lval2 = 0;
    2561      631445 :         double dval1 = 0.0, dval2 = 0.0;
    2562             : 
    2563     1569645 :         if ((ret1 = is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
    2564      306755 :                 (ret2 = is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) {
    2565             : #if ZEND_ULONG_MAX == 0xFFFFFFFF
    2566             :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0. &&
    2567             :                         ((oflow1 == 1 && dval1 > 9007199254740991. /*0x1FFFFFFFFFFFFF*/)
    2568             :                         || (oflow1 == -1 && dval1 < -9007199254740991.))) {
    2569             : #else
    2570      306600 :                 if (oflow1 != 0 && oflow1 == oflow2 && dval1 - dval2 == 0.) {
    2571             : #endif
    2572             :                         /* both values are integers overflown to the same side, and the
    2573             :                          * double comparison may have resulted in crucial accuracy lost */
    2574        1111 :                         goto string_cmp;
    2575             :                 }
    2576      305489 :                 if ((ret1 == IS_DOUBLE) || (ret2 == IS_DOUBLE)) {
    2577      100106 :                         if (ret1 != IS_DOUBLE) {
    2578          35 :                                 if (oflow2) {
    2579             :                                         /* 2nd operand is integer > LONG_MAX (oflow2==1) or < LONG_MIN (-1) */
    2580           3 :                                         return -1 * oflow2;
    2581             :                                 }
    2582          32 :                                 dval1 = (double) lval1;
    2583      100071 :                         } else if (ret2 != IS_DOUBLE) {
    2584          13 :                                 if (oflow1) {
    2585           0 :                                         return oflow1;
    2586             :                                 }
    2587          13 :                                 dval2 = (double) lval2;
    2588      100058 :                         } else if (dval1 == dval2 && !zend_finite(dval1)) {
    2589             :                                 /* Both values overflowed and have the same sign,
    2590             :                                  * so a numeric comparison would be inaccurate */
    2591           4 :                                 goto string_cmp;
    2592             :                         }
    2593      100099 :                         dval1 = dval1 - dval2;
    2594      100099 :                         return ZEND_NORMALIZE_BOOL(dval1);
    2595             :                 } else { /* they both have to be long's */
    2596      205383 :                         return lval1 > lval2 ? 1 : (lval1 < lval2 ? -1 : 0);
    2597             :                 }
    2598             :         } else {
    2599             :                 int strcmp_ret;
    2600             : string_cmp:
    2601      325960 :                 strcmp_ret = zend_binary_strcmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
    2602      325960 :                 return ZEND_NORMALIZE_BOOL(strcmp_ret);
    2603             :         }
    2604             : }
    2605             : /* }}} */
    2606             : 
    2607        2874 : static int hash_zval_compare_function(zval *z1, zval *z2) /* {{{ */
    2608             : {
    2609             :         zval result;
    2610             : 
    2611        2874 :         if (compare_function(&result, z1, z2)==FAILURE) {
    2612           0 :                 return 1;
    2613             :         }
    2614        2874 :         return Z_LVAL(result);
    2615             : }
    2616             : /* }}} */
    2617             : 
    2618        1079 : ZEND_API int zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2) /* {{{ */
    2619             : {
    2620        1079 :         return ht1 == ht2 ? 0 : zend_hash_compare(ht1, ht2, (compare_func_t) hash_zval_compare_function, 0);
    2621             : }
    2622             : /* }}} */
    2623             : 
    2624         762 : ZEND_API int zend_compare_arrays(zval *a1, zval *a2) /* {{{ */
    2625             : {
    2626         762 :         return zend_compare_symbol_tables(Z_ARRVAL_P(a1), Z_ARRVAL_P(a2));
    2627             : }
    2628             : /* }}} */
    2629             : 
    2630           1 : ZEND_API int zend_compare_objects(zval *o1, zval *o2) /* {{{ */
    2631             : {
    2632           1 :         if (Z_OBJ_P(o1) == Z_OBJ_P(o2)) {
    2633           1 :                 return 0;
    2634             :         }
    2635             : 
    2636           0 :         if (Z_OBJ_HT_P(o1)->compare_objects == NULL) {
    2637           0 :                 return 1;
    2638             :         } else {
    2639           0 :                 return Z_OBJ_HT_P(o1)->compare_objects(o1, o2);
    2640             :         }
    2641             : }
    2642             : /* }}} */
    2643             : 
    2644           0 : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC) /* {{{ */
    2645             : {
    2646             :         zend_string *str;
    2647             : 
    2648           0 :         str = zend_strpprintf(0, "%.*G", (int) EG(precision), (double)Z_DVAL_P(op));
    2649           0 :         ZVAL_NEW_STR(op, str);
    2650           0 : }
    2651             : /* }}} */
    2652             : 
    2653      386473 : ZEND_API zend_string *zend_long_to_str(zend_long num) /* {{{ */
    2654             : {
    2655             :         char buf[MAX_LENGTH_OF_LONG + 1];
    2656      386473 :         char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
    2657      772946 :         return zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
    2658             : }
    2659             : /* }}} */
    2660             : 
    2661        2550 : ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval) /* {{{ */ {
    2662        5100 :     return is_numeric_string_ex(str->val, str->len, lval, dval, -1, NULL);
    2663             : }
    2664             : /* }}} */
    2665             : 
    2666      962068 : ZEND_API zend_uchar _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info) /* {{{ */
    2667             : {
    2668             :         const char *ptr;
    2669      962068 :         int base = 10, digits = 0, dp_or_e = 0;
    2670      962068 :         double local_dval = 0.0;
    2671             :         zend_uchar type;
    2672             : 
    2673      962068 :         if (!length) {
    2674        1441 :                 return 0;
    2675             :         }
    2676             : 
    2677      960627 :         if (oflow_info != NULL) {
    2678      825178 :                 *oflow_info = 0;
    2679             :         }
    2680             : 
    2681             :         /* Skip any whitespace
    2682             :          * This is much faster than the isspace() function */
    2683     1923006 :         while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
    2684        1752 :                 str++;
    2685        1752 :                 length--;
    2686             :         }
    2687      960627 :         ptr = str;
    2688             : 
    2689      960627 :         if (*ptr == '-' || *ptr == '+') {
    2690        2401 :                 ptr++;
    2691             :         }
    2692             : 
    2693     1518025 :         if (ZEND_IS_DIGIT(*ptr)) {
    2694             :                 /* Handle hex numbers
    2695             :                  * str is used instead of ptr to disallow signs and keep old behavior */
    2696      762620 :                 if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
    2697         236 :                         base = 16;
    2698         236 :                         ptr += 2;
    2699             :                 }
    2700             : 
    2701             :                 /* Skip any leading 0s */
    2702     1791170 :                 while (*ptr == '0') {
    2703      265930 :                         ptr++;
    2704             :                 }
    2705             : 
    2706             :                 /* Count the number of digits. If a decimal point/exponent is found,
    2707             :                  * it's a double. Otherwise, if there's a dval or no need to check for
    2708             :                  * a full match, stop when there are too many digits for a long */
    2709    10897834 :                 for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
    2710             : check_digits:
    2711     5446701 :                         if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
    2712     4686297 :                                 continue;
    2713      760404 :                         } else if (base == 10) {
    2714      760168 :                                 if (*ptr == '.' && dp_or_e < 1) {
    2715             :                                         goto process_double;
    2716      557478 :                                 } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
    2717         357 :                                         const char *e = ptr + 1;
    2718             : 
    2719         357 :                                         if (*e == '-' || *e == '+') {
    2720           9 :                                                 ptr = e++;
    2721             :                                         }
    2722         357 :                                         if (ZEND_IS_DIGIT(*e)) {
    2723         314 :                                                 goto process_double;
    2724             :                                         }
    2725             :                                 }
    2726             :                         }
    2727             : 
    2728      557400 :                         break;
    2729             :                 }
    2730             : 
    2731      559636 :                 if (base == 10) {
    2732      559400 :                         if (digits >= MAX_LENGTH_OF_LONG) {
    2733        2238 :                                 if (oflow_info != NULL) {
    2734        2233 :                                         *oflow_info = *str == '-' ? -1 : 1;
    2735             :                                 }
    2736        2238 :                                 dp_or_e = -1;
    2737        2238 :                                 goto process_double;
    2738             :                         }
    2739         236 :                 } else if (!(digits < SIZEOF_ZEND_LONG * 2 || (digits == SIZEOF_ZEND_LONG * 2 && ptr[-digits] <= '7'))) {
    2740           0 :                         if (dval) {
    2741           0 :                                 local_dval = zend_hex_strtod(str, &ptr);
    2742             :                         }
    2743           0 :                         if (oflow_info != NULL) {
    2744           0 :                                 *oflow_info = 1;
    2745             :                         }
    2746           0 :                         type = IS_DOUBLE;
    2747             :                 }
    2748      403391 :         } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
    2749             : process_double:
    2750      205404 :                 type = IS_DOUBLE;
    2751             : 
    2752             :                 /* If there's a dval, do the conversion; else continue checking
    2753             :                  * the digits if we need to check for a full match */
    2754      205404 :                 if (dval) {
    2755      205382 :                         local_dval = zend_strtod(str, &ptr);
    2756          22 :                 } else if (allow_errors != 1 && dp_or_e != -1) {
    2757          20 :                         dp_or_e = (*ptr++ == '.') ? 1 : 2;
    2758          20 :                         goto check_digits;
    2759             :                 }
    2760             :         } else {
    2761      197845 :                 return 0;
    2762             :         }
    2763             : 
    2764      762782 :         if (ptr != str + length) {
    2765       14867 :                 if (!allow_errors) {
    2766       14031 :                         return 0;
    2767             :                 }
    2768         836 :                 if (allow_errors == -1) {
    2769          62 :                         zend_error(E_NOTICE, "A non well formed numeric value encountered");
    2770             :                 }
    2771             :         }
    2772             : 
    2773      748751 :         if (type == IS_LONG) {
    2774      544148 :                 if (digits == MAX_LENGTH_OF_LONG - 1) {
    2775         175 :                         int cmp = strcmp(&ptr[-digits], long_min_digits);
    2776             : 
    2777         175 :                         if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
    2778           3 :                                 if (dval) {
    2779           3 :                                         *dval = zend_strtod(str, NULL);
    2780             :                                 }
    2781           3 :                                 if (oflow_info != NULL) {
    2782           3 :                                         *oflow_info = *str == '-' ? -1 : 1;
    2783             :                                 }
    2784             : 
    2785           3 :                                 return IS_DOUBLE;
    2786             :                         }
    2787             :                 }
    2788             : 
    2789      544145 :                 if (lval) {
    2790      544084 :                         *lval = ZEND_STRTOL(str, NULL, base);
    2791             :                 }
    2792             : 
    2793      544145 :                 return IS_LONG;
    2794             :         } else {
    2795      204603 :                 if (dval) {
    2796      204585 :                         *dval = local_dval;
    2797             :                 }
    2798             : 
    2799      204603 :                 return IS_DOUBLE;
    2800             :         }
    2801             : }
    2802             : /* }}} */
    2803             : 
    2804             : /* 
    2805             :  * String matching - Sunday algorithm
    2806             :  * http://www.iti.fh-flensburg.de/lang/algorithmen/pattern/sundayen.htm
    2807             :  */
    2808             : static zend_always_inline void zend_memnstr_ex_pre(unsigned int td[], const char *needle, size_t needle_len, int reverse) /* {{{ */ {
    2809             :         int i;
    2810             : 
    2811     3964482 :         for (i = 0; i < 256; i++) {
    2812     3949056 :                 td[i] = needle_len + 1;
    2813             :         }
    2814             : 
    2815       15426 :         if (reverse) {
    2816           0 :                 for (i = needle_len - 1; i >= 0; i--) {
    2817           0 :                         td[(unsigned char)needle[i]] = i + 1;
    2818             :                 }
    2819             :         } else {
    2820      244821 :                 for (i = 0; i < needle_len; i++) {
    2821      229395 :                         td[(unsigned char)needle[i]] = (int)needle_len - i;
    2822             :                 }
    2823             :         }
    2824             : }
    2825             : /* }}} */
    2826             : 
    2827       15426 : ZEND_API const char* zend_memnstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end) /* {{{ */
    2828             : {
    2829             :         unsigned int td[256];
    2830             :         register size_t i;
    2831             :         register const char *p;
    2832             : 
    2833       15426 :         if (needle_len == 0 || (end - haystack) == 0) {
    2834           0 :                 return NULL;
    2835             :         }
    2836             : 
    2837             :         zend_memnstr_ex_pre(td, needle, needle_len, 0);
    2838             : 
    2839       15426 :         p = haystack;
    2840       15426 :         end -= needle_len;
    2841             : 
    2842     4031854 :         while (p <= end) {
    2843     4116038 :                 for (i = 0; i < needle_len; i++) {
    2844     4111297 :                         if (needle[i] != p[i]) {
    2845     4001002 :                                 break;
    2846             :                         }
    2847             :                 }
    2848     4005743 :                 if (i == needle_len) {
    2849        4741 :                         return p;
    2850             :                 }
    2851     4001002 :                 p += td[(unsigned char)(p[needle_len])];
    2852             :         }
    2853             : 
    2854       10685 :         return NULL;
    2855             : }
    2856             : /* }}} */
    2857             : 
    2858           0 : ZEND_API const char* zend_memnrstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end) /* {{{ */
    2859             : {
    2860             :         unsigned int td[256];
    2861             :         register size_t i;
    2862             :         register const char *p;
    2863             : 
    2864           0 :         if (needle_len == 0 || (end - haystack) == 0) {
    2865           0 :                 return NULL;
    2866             :         }
    2867             : 
    2868             :         zend_memnstr_ex_pre(td, needle, needle_len, 1);
    2869             : 
    2870           0 :         p = end;
    2871           0 :         p -= needle_len;
    2872             : 
    2873           0 :         while (p >= haystack) {
    2874           0 :                 for (i = 0; i < needle_len; i++) {
    2875           0 :                         if (needle[i] != p[i]) {
    2876           0 :                                 break;
    2877             :                         }
    2878             :                 }
    2879             : 
    2880           0 :                 if (i == needle_len) {
    2881           0 :                         return (const char *)p;
    2882             :                 }
    2883             :                 
    2884           0 :                 if (UNEXPECTED(p == haystack)) {
    2885           0 :                         return NULL;
    2886             :                 }
    2887             : 
    2888           0 :                 p -= td[(unsigned char)(p[-1])];
    2889             :         }
    2890             : 
    2891           0 :         return NULL;
    2892             : }
    2893             : /* }}} */
    2894             : 
    2895             : /*
    2896             :  * Local variables:
    2897             :  * tab-width: 4
    2898             :  * c-basic-offset: 4
    2899             :  * indent-tabs-mode: t
    2900             :  * End:
    2901             :  */

Generated by: LCOV version 1.10

Generated at Mon, 26 Jan 2015 14:46:41 +0000 (4 days ago)

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