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.h (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 257 265 97.0 %
Date: 2015-04-30 Functions: 0 0 -
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             : #ifndef ZEND_OPERATORS_H
      23             : #define ZEND_OPERATORS_H
      24             : 
      25             : #include <errno.h>
      26             : #include <math.h>
      27             : #include <assert.h>
      28             : 
      29             : #ifdef __GNUC__
      30             : #include <stddef.h>
      31             : #endif
      32             : 
      33             : #ifdef HAVE_IEEEFP_H
      34             : #include <ieeefp.h>
      35             : #endif
      36             : 
      37             : #include "zend_strtod.h"
      38             : #include "zend_multiply.h"
      39             : 
      40             : #if 0&&HAVE_BCMATH
      41             : #include "ext/bcmath/libbcmath/src/bcmath.h"
      42             : #endif
      43             : 
      44             : #define LONG_SIGN_MASK (((zend_long)1) << (8*sizeof(zend_long)-1))
      45             : 
      46             : BEGIN_EXTERN_C()
      47             : ZEND_API int add_function(zval *result, zval *op1, zval *op2);
      48             : ZEND_API int sub_function(zval *result, zval *op1, zval *op2);
      49             : ZEND_API int mul_function(zval *result, zval *op1, zval *op2);
      50             : ZEND_API int pow_function(zval *result, zval *op1, zval *op2);
      51             : ZEND_API int div_function(zval *result, zval *op1, zval *op2);
      52             : ZEND_API int mod_function(zval *result, zval *op1, zval *op2);
      53             : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2);
      54             : ZEND_API int boolean_not_function(zval *result, zval *op1);
      55             : ZEND_API int bitwise_not_function(zval *result, zval *op1);
      56             : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2);
      57             : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2);
      58             : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2);
      59             : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2);
      60             : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2);
      61             : ZEND_API int concat_function(zval *result, zval *op1, zval *op2);
      62             : 
      63             : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2);
      64             : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2);
      65             : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2);
      66             : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2);
      67             : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2);
      68             : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2);
      69             : 
      70             : ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only);
      71             : ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce);
      72             : 
      73             : /**
      74             :  * Checks whether the string "str" with length "length" is numeric. The value
      75             :  * of allow_errors determines whether it's required to be entirely numeric, or
      76             :  * just its prefix. Leading whitespace is allowed.
      77             :  *
      78             :  * The function returns 0 if the string did not contain a valid number; IS_LONG
      79             :  * if it contained a number that fits within the range of a long; or IS_DOUBLE
      80             :  * if the number was out of long range or contained a decimal point/exponent.
      81             :  * The number's value is returned into the respective pointer, *lval or *dval,
      82             :  * if that pointer is not NULL.
      83             :  *
      84             :  * This variant also gives information if a string that represents an integer
      85             :  * could not be represented as such due to overflow. It writes 1 to oflow_info
      86             :  * if the integer is larger than ZEND_LONG_MAX and -1 if it's smaller than ZEND_LONG_MIN.
      87             :  */
      88             : 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);
      89             : 
      90             : ZEND_API const char* zend_memnstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end);
      91             : ZEND_API const char* zend_memnrstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end);
      92             : 
      93             : END_EXTERN_C()
      94             : 
      95             : #if SIZEOF_ZEND_LONG == 4
      96             : #       define ZEND_DOUBLE_FITS_LONG(d) (!((d) > ZEND_LONG_MAX || (d) < ZEND_LONG_MIN))
      97             : #else
      98             :         /* >= as (double)ZEND_LONG_MAX is outside signed range */
      99             : #       define ZEND_DOUBLE_FITS_LONG(d) (!((d) >= ZEND_LONG_MAX || (d) < ZEND_LONG_MIN))
     100             : #endif
     101             : 
     102             : #if ZEND_DVAL_TO_LVAL_CAST_OK
     103             : static zend_always_inline zend_long zend_dval_to_lval(double d)
     104             : {
     105             :     if (EXPECTED(zend_finite(d)) && EXPECTED(!zend_isnan(d))) {
     106             :         return (zend_long)d;
     107             :     } else {
     108             :         return 0;
     109             :     }
     110             : }
     111             : #elif SIZEOF_ZEND_LONG == 4
     112             : static zend_always_inline zend_long zend_dval_to_lval(double d)
     113             : {
     114             :         if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
     115             :                 return 0;
     116             :         } else if (!ZEND_DOUBLE_FITS_LONG(d)) {
     117             :                 double  two_pow_32 = pow(2., 32.),
     118             :                                 dmod;
     119             : 
     120             :                 dmod = fmod(d, two_pow_32);
     121             :                 if (dmod < 0) {
     122             :                         /* we're going to make this number positive; call ceil()
     123             :                          * to simulate rounding towards 0 of the negative number */
     124             :                         dmod = ceil(dmod) + two_pow_32;
     125             :                 }
     126             :                 return (zend_long)(zend_ulong)dmod;
     127             :         }
     128             :         return (zend_long)d;
     129             : }
     130             : #else
     131             : static zend_always_inline zend_long zend_dval_to_lval(double d)
     132             : {
     133       26993 :         if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
     134           3 :                 return 0;
     135       26990 :         } else if (!ZEND_DOUBLE_FITS_LONG(d)) {
     136         140 :                 double  two_pow_64 = pow(2., 64.),
     137             :                                 dmod;
     138             : 
     139         140 :                 dmod = fmod(d, two_pow_64);
     140         140 :                 if (dmod < 0) {
     141             :                         /* no need to call ceil; original double must have had no
     142             :                          * fractional part, hence dmod does not have one either */
     143           7 :                         dmod += two_pow_64;
     144             :                 }
     145         140 :                 return (zend_long)(zend_ulong)dmod;
     146             :         }
     147       26850 :         return (zend_long)d;
     148             : }
     149             : #endif
     150             : /* }}} */
     151             : 
     152             : #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
     153             : #define ZEND_IS_XDIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
     154             : 
     155             : static zend_always_inline zend_uchar is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info)
     156             : {
     157     1098521 :         if (*str > '9') {
     158      136358 :                 return 0;
     159             :         }
     160      962163 :         return _is_numeric_string_ex(str, length, lval, dval, allow_errors, oflow_info);
     161             : }
     162             : 
     163             : static zend_always_inline zend_uchar is_numeric_string(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors) {
     164      157309 :     return is_numeric_string_ex(str, length, lval, dval, allow_errors, NULL);
     165             : }
     166             : 
     167             : ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval);
     168             : 
     169             : static zend_always_inline const char *
     170             : zend_memnstr(const char *haystack, const char *needle, size_t needle_len, char *end)
     171             : {
     172     2692191 :         const char *p = haystack;
     173     2692191 :         const char ne = needle[needle_len-1];
     174             :         ptrdiff_t off_p;
     175             :         size_t off_s;
     176             : 
     177     2692191 :         if (needle_len == 1) {
     178     1876120 :                 return (const char *)memchr(p, *needle, (end-p));
     179             :         }
     180             : 
     181      816071 :         off_p = end - haystack;
     182      816071 :         off_s = (off_p > 0) ? (size_t)off_p : 0;
     183             : 
     184      816071 :         if (needle_len > off_s) {
     185       10495 :                 return NULL;
     186             :         }
     187             : 
     188      805576 :         if (EXPECTED(off_s < 1024 || needle_len < 3)) {
     189      790144 :                 end -= needle_len;
     190             : 
     191     3524316 :                 while (p <= end) {
     192     3457615 :                         if ((p = (const char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
     193      522306 :                                 if (!memcmp(needle, p, needle_len-1)) {
     194      210814 :                                         return p;
     195             :                                 }
     196             :                         }
     197             : 
     198     3246801 :                         if (p == NULL) {
     199      512629 :                                 return NULL;
     200             :                         }
     201             : 
     202     2734172 :                         p++;
     203             :                 }
     204             : 
     205       66701 :                 return NULL;
     206             :         } else {
     207       15432 :                 return zend_memnstr_ex(haystack, needle, needle_len, end);
     208             :         }
     209             : }
     210             : 
     211             : static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t n)
     212             : {
     213             :         register const unsigned char *e;
     214     3373146 :         if (n <= 0) {
     215         442 :                 return NULL;
     216             :         }
     217             : 
     218    49455011 :         for (e = (const unsigned char *)s + n - 1; e >= (const unsigned char *)s; e--) {
     219    46119936 :                 if (*e == (const unsigned char)c) {
     220       37629 :                         return (const void *)e;
     221             :                 }
     222             :         }
     223     3335075 :         return NULL;
     224             : }
     225             : 
     226             : 
     227             : static zend_always_inline const char *
     228             : zend_memnrstr(const char *haystack, const char *needle, size_t needle_len, char *end)
     229             : {
     230         578 :     const char *p = end;
     231         578 :     const char ne = needle[needle_len-1];
     232             :     ptrdiff_t off_p;
     233             :     size_t off_s;
     234             : 
     235         578 :     if (needle_len == 1) {
     236         486 :         return (const char *)zend_memrchr(haystack, *needle, (p - haystack));
     237             :     }
     238             : 
     239         335 :     off_p = end - haystack;
     240         335 :     off_s = (off_p > 0) ? (size_t)off_p : 0;
     241             : 
     242         335 :     if (needle_len > off_s) {
     243          29 :         return NULL;
     244             :     }
     245             : 
     246         306 :         if (EXPECTED(off_s < 1024 || needle_len < 3)) {
     247         306 :                 p -= needle_len;
     248             : 
     249             :                 do {
     250        1180 :                         if ((p = (const char *)zend_memrchr(haystack, *needle, (p - haystack) + 1)) && ne == p[needle_len-1]) {
     251         236 :                                 if (!memcmp(needle, p, needle_len - 1)) {
     252         208 :                                         return p;
     253             :                                 }
     254             :                         }
     255         382 :                 } while (p-- >= haystack);
     256             : 
     257          98 :                 return NULL;
     258             :         } else {
     259           0 :                 return zend_memnrstr_ex(haystack, needle, needle_len, end);
     260             :         }
     261             : }
     262             : 
     263             : BEGIN_EXTERN_C()
     264             : ZEND_API int increment_function(zval *op1);
     265             : ZEND_API int decrement_function(zval *op2);
     266             : 
     267             : ZEND_API void convert_scalar_to_number(zval *op);
     268             : ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC);
     269             : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
     270             : ZEND_API void convert_to_long(zval *op);
     271             : ZEND_API void convert_to_double(zval *op);
     272             : ZEND_API void convert_to_long_base(zval *op, int base);
     273             : ZEND_API void convert_to_null(zval *op);
     274             : ZEND_API void convert_to_boolean(zval *op);
     275             : ZEND_API void convert_to_array(zval *op);
     276             : ZEND_API void convert_to_object(zval *op);
     277             : ZEND_API void multi_convert_to_long_ex(int argc, ...);
     278             : ZEND_API void multi_convert_to_double_ex(int argc, ...);
     279             : ZEND_API void multi_convert_to_string_ex(int argc, ...);
     280             : 
     281             : ZEND_API zend_long _zval_get_long_func(zval *op);
     282             : ZEND_API double _zval_get_double_func(zval *op);
     283             : ZEND_API zend_string *_zval_get_string_func(zval *op);
     284             : 
     285             : static zend_always_inline zend_long _zval_get_long(zval *op) {
     286      368804 :         return Z_TYPE_P(op) == IS_LONG ? Z_LVAL_P(op) : _zval_get_long_func(op);
     287             : }
     288             : static zend_always_inline double _zval_get_double(zval *op) {
     289      206231 :         return Z_TYPE_P(op) == IS_DOUBLE ? Z_DVAL_P(op) : _zval_get_double_func(op);
     290             : }
     291             : static zend_always_inline zend_string *_zval_get_string(zval *op) {
     292     6581628 :         return Z_TYPE_P(op) == IS_STRING ? zend_string_copy(Z_STR_P(op)) : _zval_get_string_func(op);
     293             : }
     294             : 
     295             : #define zval_get_long(op) _zval_get_long((op))
     296             : #define zval_get_double(op) _zval_get_double((op))
     297             : #define zval_get_string(op) _zval_get_string((op))
     298             : 
     299             : ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2);
     300             : ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2);
     301             : #define convert_to_cstring(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_cstring((op) ZEND_FILE_LINE_CC); }
     302             : #define convert_to_string(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
     303             : 
     304             : 
     305             : ZEND_API int zend_is_true(zval *op);
     306             : ZEND_API int zend_object_is_true(zval *op);
     307             : 
     308             : #define zval_is_true(op) \
     309             :         zend_is_true(op)
     310             : 
     311             : static zend_always_inline int i_zend_is_true(zval *op)
     312             : {
     313             :         int result;
     314             : 
     315             : again:
     316     2704034 :         switch (Z_TYPE_P(op)) {
     317             :                 case IS_UNDEF:
     318             :                 case IS_NULL:
     319             :                 case IS_FALSE:
     320      121537 :                         result = 0;
     321             :                         break;
     322             :                 case IS_TRUE:
     323       69178 :                         result = 1;
     324             :                         break;
     325             :                 case IS_LONG:
     326     2005741 :                         result = (Z_LVAL_P(op)?1:0);
     327             :                         break;
     328             :                 case IS_RESOURCE:
     329       42553 :                         result = (Z_RES_HANDLE_P(op)?1:0);
     330             :                         break;
     331             :                 case IS_DOUBLE:
     332         255 :                         result = (Z_DVAL_P(op) ? 1 : 0);
     333             :                         break;
     334             :                 case IS_STRING:
     335      162001 :                         if (Z_STRLEN_P(op) == 0
     336      105030 :                                 || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
     337        9509 :                                 result = 0;
     338             :                         } else {
     339       47462 :                                 result = 1;
     340             :                         }
     341             :                         break;
     342             :                 case IS_ARRAY:
     343      100348 :                         result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     344             :                         break;
     345             :                 case IS_OBJECT:
     346       92371 :                         result = zend_object_is_true(op);
     347             :                         break;
     348             :                 case IS_REFERENCE:
     349      215080 :                         op = Z_REFVAL_P(op);
     350             :                         goto again;
     351             :                         break;
     352             :                 default:
     353           0 :                         result = 0;
     354             :                         break;
     355             :         }
     356     2488953 :         return result;
     357             : }
     358             : 
     359             : ZEND_API int compare_function(zval *result, zval *op1, zval *op2);
     360             : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2);
     361             : ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive);
     362             : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2);
     363             : ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2);
     364             : #if HAVE_STRCOLL
     365             : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2);
     366             : #endif
     367             : 
     368             : ZEND_API void zend_str_tolower(char *str, size_t length);
     369             : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, size_t length);
     370             : ZEND_API char *zend_str_tolower_dup(const char *source, size_t length);
     371             : ZEND_API zend_string *zend_string_tolower(zend_string *str);
     372             : 
     373             : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
     374             : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
     375             : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
     376             : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3);
     377             : ZEND_API int zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2);
     378             : ZEND_API int zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     379             : ZEND_API int zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2);
     380             : ZEND_API int zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     381             : ZEND_API int zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2);
     382             : ZEND_API int zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     383             : 
     384             : ZEND_API zend_long zendi_smart_strcmp(zval *s1, zval *s2);
     385             : ZEND_API int zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2);
     386             : ZEND_API int zend_compare_arrays(zval *a1, zval *a2);
     387             : ZEND_API int zend_compare_objects(zval *o1, zval *o2);
     388             : 
     389             : ZEND_API int zend_atoi(const char *str, int str_len);
     390             : ZEND_API zend_long zend_atol(const char *str, int str_len);
     391             : 
     392             : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
     393             : 
     394             : #define convert_to_ex_master(pzv, lower_type, upper_type)       \
     395             :         if (Z_TYPE_P(pzv)!=upper_type) {                                        \
     396             :                 SEPARATE_ZVAL_IF_NOT_REF(pzv);                                          \
     397             :                 convert_to_##lower_type(pzv);                                           \
     398             :         }
     399             : 
     400             : #define convert_to_explicit_type(pzv, type)             \
     401             :         do {                                                                            \
     402             :                 switch (type) {                                                 \
     403             :                         case IS_NULL:                                           \
     404             :                                 convert_to_null(pzv);                   \
     405             :                                 break;                                                  \
     406             :                         case IS_LONG:                                           \
     407             :                                 convert_to_long(pzv);                   \
     408             :                                 break;                                                  \
     409             :                         case IS_DOUBLE:                                         \
     410             :                                 convert_to_double(pzv);                 \
     411             :                                 break;                                                  \
     412             :                         case _IS_BOOL:                                          \
     413             :                                 convert_to_boolean(pzv);                \
     414             :                                 break;                                                  \
     415             :                         case IS_ARRAY:                                          \
     416             :                                 convert_to_array(pzv);                  \
     417             :                                 break;                                                  \
     418             :                         case IS_OBJECT:                                         \
     419             :                                 convert_to_object(pzv);                 \
     420             :                                 break;                                                  \
     421             :                         case IS_STRING:                                         \
     422             :                                 convert_to_string(pzv);                 \
     423             :                                 break;                                                  \
     424             :                         default:                                                        \
     425             :                                 assert(0);                                              \
     426             :                                 break;                                                  \
     427             :                 }                                                                               \
     428             :         } while (0);
     429             : 
     430             : #define convert_to_explicit_type_ex(pzv, str_type)      \
     431             :         if (Z_TYPE_P(pzv) != str_type) {                                \
     432             :                 SEPARATE_ZVAL_IF_NOT_REF(pzv);                          \
     433             :                 convert_to_explicit_type(pzv, str_type);        \
     434             :         }
     435             : 
     436             : #define convert_to_boolean_ex(pzv)      convert_to_ex_master(pzv, boolean, _IS_BOOL)
     437             : #define convert_to_long_ex(pzv)         convert_to_ex_master(pzv, long, IS_LONG)
     438             : #define convert_to_double_ex(pzv)       convert_to_ex_master(pzv, double, IS_DOUBLE)
     439             : #define convert_to_string_ex(pzv)       convert_to_ex_master(pzv, string, IS_STRING)
     440             : #define convert_to_array_ex(pzv)        convert_to_ex_master(pzv, array, IS_ARRAY)
     441             : #define convert_to_object_ex(pzv)       convert_to_ex_master(pzv, object, IS_OBJECT)
     442             : #define convert_to_null_ex(pzv)         convert_to_ex_master(pzv, null, IS_NULL)
     443             : 
     444             : #define convert_scalar_to_number_ex(pzv)                                                        \
     445             :         if (Z_TYPE_P(pzv)!=IS_LONG && Z_TYPE_P(pzv)!=IS_DOUBLE) {               \
     446             :                 SEPARATE_ZVAL_IF_NOT_REF(pzv);                                                          \
     447             :                 convert_scalar_to_number(pzv);                                  \
     448             :         }
     449             : 
     450             : #if HAVE_SETLOCALE && defined(ZEND_WIN32) && !defined(ZTS) && defined(_MSC_VER) && (_MSC_VER >= 1400)
     451             : /* This is performance improvement of tolower() on Windows and VC2005
     452             :  * Gives 10-18% on bench.php
     453             :  */
     454             : #define ZEND_USE_TOLOWER_L 1
     455             : #endif
     456             : 
     457             : #ifdef ZEND_USE_TOLOWER_L
     458             : ZEND_API void zend_update_current_locale(void);
     459             : #else
     460             : #define zend_update_current_locale()
     461             : #endif
     462             : 
     463             : /* The offset in bytes between the value and type fields of a zval */
     464             : #define ZVAL_OFFSETOF_TYPE      \
     465             :         (offsetof(zval, u1.type_info) - offsetof(zval, value))
     466             : 
     467             : static zend_always_inline int fast_increment_function(zval *op1)
     468             : {
     469     4709349 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     470             : #if defined(__GNUC__) && defined(__i386__)
     471             :                 __asm__(
     472             :                         "incl (%0)\n\t"
     473             :                         "jno  0f\n\t"
     474             :                         "movl $0x0, (%0)\n\t"
     475             :                         "movl $0x41e00000, 0x4(%0)\n\t"
     476             :                         "movl %1, %c2(%0)\n"
     477             :                         "0:"
     478             :                         :
     479             :                         : "r"(&op1->value),
     480             :                           "n"(IS_DOUBLE),
     481             :                           "n"(ZVAL_OFFSETOF_TYPE)
     482             :                         : "cc");
     483             : #elif defined(__GNUC__) && defined(__x86_64__)
     484     4709349 :                 __asm__(
     485             :                         "incq (%0)\n\t"
     486             :                         "jno  0f\n\t"
     487             :                         "movl $0x0, (%0)\n\t"
     488             :                         "movl $0x43e00000, 0x4(%0)\n\t"
     489             :                         "movl %1, %c2(%0)\n"
     490             :                         "0:"
     491             :                         :
     492     4709349 :                         : "r"(&op1->value),
     493             :                           "n"(IS_DOUBLE),
     494             :                           "n"(ZVAL_OFFSETOF_TYPE)
     495             :                         : "cc");
     496             : #elif defined(__GNUC__) && defined(__powerpc64__)
     497             :                 __asm__(
     498             :                         "ld 14, 0(%0)\n\t"
     499             :                         "li 15, 1\n\t"
     500             :                         "li 16, 0\n\t"
     501             :                         "mtxer 16\n\t"
     502             :                         "addo. 14, 14, 15\n\t"
     503             :                         "std 14, 0(%0)\n\t"
     504             :                         "bns+  0f\n\t"
     505             :                         "xor 14, 14, 14\n\t"
     506             :                         "lis 15, 0x43e00000@h\n\t"
     507             :                         "ori 15, 15, 0x43e00000@l\n\t"
     508             : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     509             :                         "stw 14, 0(%0)\n\t"
     510             :                         "stw 15, 0x4(%0)\n\t"
     511             : #else
     512             :                         "stw 14, 0x4(%0)\n\t"
     513             :                         "stw 15, 0(%0)\n\t"
     514             : #endif
     515             :                         "li 14, %1\n\t"
     516             :                         "stw 14, %c2(%0)\n"
     517             :                         "0:"
     518             :                         :
     519             :                         : "r"(&op1->value),
     520             :                           "n"(IS_DOUBLE),
     521             :                           "n"(ZVAL_OFFSETOF_TYPE)
     522             :                         : "r14", "r15", "r16", "cc");
     523             : #else
     524             :                 if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
     525             :                         /* switch to double */
     526             :                         ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
     527             :                 } else {
     528             :                         Z_LVAL_P(op1)++;
     529             :                 }
     530             : #endif
     531     4709349 :                 return SUCCESS;
     532             :         }
     533           0 :         return increment_function(op1);
     534             : }
     535             : 
     536             : static zend_always_inline int fast_decrement_function(zval *op1)
     537             : {
     538      249782 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     539             : #if defined(__GNUC__) && defined(__i386__)
     540             :                 __asm__(
     541             :                         "decl (%0)\n\t"
     542             :                         "jno  0f\n\t"
     543             :                         "movl $0x00200000, (%0)\n\t"
     544             :                         "movl $0xc1e00000, 0x4(%0)\n\t"
     545             :                         "movl %1,%c2(%0)\n"
     546             :                         "0:"
     547             :                         :
     548             :                         : "r"(&op1->value),
     549             :                           "n"(IS_DOUBLE),
     550             :                           "n"(ZVAL_OFFSETOF_TYPE)
     551             :                         : "cc");
     552             : #elif defined(__GNUC__) && defined(__x86_64__)
     553      249782 :                 __asm__(
     554             :                         "decq (%0)\n\t"
     555             :                         "jno  0f\n\t"
     556             :                         "movl $0x00000000, (%0)\n\t"
     557             :                         "movl $0xc3e00000, 0x4(%0)\n\t"
     558             :                         "movl %1,%c2(%0)\n"
     559             :                         "0:"
     560             :                         :
     561      249782 :                         : "r"(&op1->value),
     562             :                           "n"(IS_DOUBLE),
     563             :                           "n"(ZVAL_OFFSETOF_TYPE)
     564             :                         : "cc");
     565             : #elif defined(__GNUC__) && defined(__powerpc64__)
     566             :                 __asm__(
     567             :                         "ld 14, 0(%0)\n\t"
     568             :                         "li 15, 1\n\t"
     569             :                         "li 16, 0\n\t"
     570             :                         "mtxer 16\n\t"
     571             :                         "subo. 14, 14, 15\n\t"
     572             :                         "std 14, 0(%0)\n\t"
     573             :                         "bns+  0f\n\t"
     574             :                         "xor 14, 14, 14\n\t"
     575             :                         "lis 15, 0xc3e00000@h\n\t"
     576             :                         "ori 15, 15, 0xc3e00000@l\n\t"
     577             : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     578             :                         "stw 14, 0(%0)\n\t"
     579             :                         "stw 15, 0x4(%0)\n\t"
     580             : #else
     581             :                         "stw 14, 0x4(%0)\n\t"
     582             :                         "stw 15, 0(%0)\n\t"
     583             : #endif
     584             :                         "li 14, %1\n\t"
     585             :                         "stw 14, %c2(%0)\n"
     586             :                         "0:"
     587             :                         :
     588             :                         : "r"(&op1->value),
     589             :                           "n"(IS_DOUBLE),
     590             :                           "n"(ZVAL_OFFSETOF_TYPE)
     591             :                         : "r14", "r15", "r16", "cc");
     592             : #else
     593             :                 if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
     594             :                         /* switch to double */
     595             :                         ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
     596             :                 } else {
     597             :                         Z_LVAL_P(op1)--;
     598             :                 }
     599             : #endif
     600      249782 :                 return SUCCESS;
     601             :         }
     602           0 :         return decrement_function(op1);
     603             : }
     604             : 
     605             : static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2)
     606             : {
     607      701655 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     608      699923 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     609             : #if defined(__GNUC__) && defined(__i386__)
     610             :                 __asm__(
     611             :                         "movl      (%1), %%eax\n\t"
     612             :                         "addl   (%2), %%eax\n\t"
     613             :                         "jo     0f\n\t"
     614             :                         "movl   %%eax, (%0)\n\t"
     615             :                         "movl   %3, %c5(%0)\n\t"
     616             :                         "jmp    1f\n"
     617             :                         "0:\n\t"
     618             :                         "fildl     (%1)\n\t"
     619             :                         "fildl     (%2)\n\t"
     620             :                         "faddp     %%st, %%st(1)\n\t"
     621             :                         "movl   %4, %c5(%0)\n\t"
     622             :                         "fstpl     (%0)\n"
     623             :                         "1:"
     624             :                         :
     625             :                         : "r"(&result->value),
     626             :                           "r"(&op1->value),
     627             :                           "r"(&op2->value),
     628             :                           "n"(IS_LONG),
     629             :                           "n"(IS_DOUBLE),
     630             :                           "n"(ZVAL_OFFSETOF_TYPE)
     631             :                         : "eax","cc");
     632             : #elif defined(__GNUC__) && defined(__x86_64__)
     633      699835 :                 __asm__(
     634             :                         "movq      (%1), %%rax\n\t"
     635             :                         "addq   (%2), %%rax\n\t"
     636             :                         "jo     0f\n\t"
     637             :                         "movq   %%rax, (%0)\n\t"
     638             :                         "movl   %3, %c5(%0)\n\t"
     639             :                         "jmp    1f\n"
     640             :                         "0:\n\t"
     641             :                         "fildq     (%1)\n\t"
     642             :                         "fildq     (%2)\n\t"
     643             :                         "faddp     %%st, %%st(1)\n\t"
     644             :                         "movl   %4, %c5(%0)\n\t"
     645             :                         "fstpl     (%0)\n"
     646             :                         "1:"
     647             :                         :
     648      699835 :                         : "r"(&result->value),
     649      699835 :                           "r"(&op1->value),
     650      699835 :                           "r"(&op2->value),
     651             :                           "n"(IS_LONG),
     652             :                           "n"(IS_DOUBLE),
     653             :                           "n"(ZVAL_OFFSETOF_TYPE)
     654             :                         : "rax","cc");
     655             : #elif defined(__GNUC__) && defined(__powerpc64__)
     656             :                 __asm__(
     657             :                         "ld 14, 0(%1)\n\t"
     658             :                         "ld 15, 0(%2)\n\t"
     659             :                         "li 16, 0 \n\t"
     660             :                         "mtxer 16\n\t"
     661             :                         "addo. 14, 14, 15\n\t"
     662             :                         "bso- 0f\n\t"
     663             :                         "std 14, 0(%0)\n\t"
     664             :                         "li 14, %3\n\t"
     665             :                         "stw 14, %c5(%0)\n\t"
     666             :                         "b 1f\n"
     667             :                         "0:\n\t"
     668             :                         "lfd 0, 0(%1)\n\t"
     669             :                         "lfd 1, 0(%2)\n\t"
     670             :                         "fcfid 0, 0\n\t"
     671             :                         "fcfid 1, 1\n\t"
     672             :                         "fadd 0, 0, 1\n\t"
     673             :                         "li 14, %4\n\t"
     674             :                         "stw 14, %c5(%0)\n\t"
     675             :                         "stfd 0, 0(%0)\n"
     676             :                         "1:"
     677             :                         :
     678             :                         : "r"(&result->value),
     679             :                           "r"(&op1->value),
     680             :                           "r"(&op2->value),
     681             :                           "n"(IS_LONG),
     682             :                           "n"(IS_DOUBLE),
     683             :                           "n"(ZVAL_OFFSETOF_TYPE)
     684             :                         : "r14","r15","r16","fr0","fr1","cc");
     685             : #else
     686             :                         /*
     687             :                          * 'result' may alias with op1 or op2, so we need to
     688             :                          * ensure that 'result' is not updated until after we
     689             :                          * have read the values of op1 and op2.
     690             :                          */
     691             : 
     692             :                         if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     693             :                                 && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
     694             :                                 ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
     695             :                         } else {
     696             :                                 ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
     697             :                         }
     698             : #endif
     699      699835 :                         return SUCCESS;
     700          88 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     701          70 :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     702          70 :                         return SUCCESS;
     703             :                 }
     704        1732 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     705        1307 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     706         202 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     707         202 :                         return SUCCESS;
     708        1105 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     709        1095 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     710        1095 :                         return SUCCESS;
     711             :                 }
     712             :         }
     713         453 :         return add_function(result, op1, op2);
     714             : }
     715             : 
     716             : static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *op2)
     717             : {
     718      357717 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     719      244219 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     720             : #if defined(__GNUC__) && defined(__i386__)
     721             :                 __asm__(
     722             :                         "movl      (%1), %%eax\n\t"
     723             :                         "subl   (%2), %%eax\n\t"
     724             :                         "jo     0f\n\t"
     725             :                         "movl   %%eax, (%0)\n\t"
     726             :                         "movl   %3, %c5(%0)\n\t"
     727             :                         "jmp    1f\n"
     728             :                         "0:\n\t"
     729             :                         "fildl     (%2)\n\t"
     730             :                         "fildl     (%1)\n\t"
     731             : #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
     732             :                         "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
     733             : #else
     734             :                         "fsubp     %%st, %%st(1)\n\t"
     735             : #endif
     736             :                         "movl   %4, %c5(%0)\n\t"
     737             :                         "fstpl     (%0)\n"
     738             :                         "1:"
     739             :                         :
     740             :                         : "r"(&result->value),
     741             :                           "r"(&op1->value),
     742             :                           "r"(&op2->value),
     743             :                           "n"(IS_LONG),
     744             :                           "n"(IS_DOUBLE),
     745             :                           "n"(ZVAL_OFFSETOF_TYPE)
     746             :                         : "eax","cc");
     747             : #elif defined(__GNUC__) && defined(__x86_64__)
     748      244152 :                 __asm__(
     749             :                         "movq      (%1), %%rax\n\t"
     750             :                         "subq   (%2), %%rax\n\t"
     751             :                         "jo     0f\n\t"
     752             :                         "movq   %%rax, (%0)\n\t"
     753             :                         "movl   %3, %c5(%0)\n\t"
     754             :                         "jmp    1f\n"
     755             :                         "0:\n\t"
     756             :                         "fildq     (%2)\n\t"
     757             :                         "fildq     (%1)\n\t"
     758             : #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
     759             :                         "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
     760             : #else
     761             :                         "fsubp     %%st, %%st(1)\n\t"
     762             : #endif
     763             :                         "movl   %4, %c5(%0)\n\t"
     764             :                         "fstpl     (%0)\n"
     765             :                         "1:"
     766             :                         :
     767      244152 :                         : "r"(&result->value),
     768      244152 :                           "r"(&op1->value),
     769      244152 :                           "r"(&op2->value),
     770             :                           "n"(IS_LONG),
     771             :                           "n"(IS_DOUBLE),
     772             :                           "n"(ZVAL_OFFSETOF_TYPE)
     773             :                         : "rax","cc");
     774             : #elif defined(__GNUC__) && defined(__powerpc64__)
     775             :                 __asm__(
     776             :                         "ld 14, 0(%1)\n\t"
     777             :                         "ld 15, 0(%2)\n\t"
     778             :                         "li 16, 0\n\t"
     779             :                         "mtxer 16\n\t"
     780             :                         "subo. 14, 14, 15\n\t"
     781             :                         "bso- 0f\n\t"
     782             :                         "std 14, 0(%0)\n\t"
     783             :                         "li 14, %3\n\t"
     784             :                         "stw 14, %c5(%0)\n\t"
     785             :                         "b 1f\n"
     786             :                         "0:\n\t"
     787             :                         "lfd 0, 0(%1)\n\t"
     788             :                         "lfd 1, 0(%2)\n\t"
     789             :                         "fcfid 0, 0\n\t"
     790             :                         "fcfid 1, 1\n\t"
     791             :                         "fsub 0, 0, 1\n\t"
     792             :                         "li 14, %4\n\t"
     793             :                         "stw 14, %c5(%0)\n\t"
     794             :                         "stfd 0, 0(%0)\n"
     795             :                         "1:"
     796             :                         :
     797             :                         : "r"(&result->value),
     798             :                           "r"(&op1->value),
     799             :                           "r"(&op2->value),
     800             :                           "n"(IS_LONG),
     801             :                           "n"(IS_DOUBLE),
     802             :                           "n"(ZVAL_OFFSETOF_TYPE)
     803             :                         : "r14","r15","r16","fr0","fr1","cc");
     804             : #else
     805             :                         ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
     806             : 
     807             :                         if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     808             :                                 && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
     809             :                                 ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
     810             :                         }
     811             : #endif
     812      244152 :                         return SUCCESS;
     813          67 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     814          50 :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     815          50 :                         return SUCCESS;
     816             :                 }
     817      113498 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     818      113278 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     819      113259 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     820      113259 :                         return SUCCESS;
     821          19 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     822          19 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     823          19 :                         return SUCCESS;
     824             :                 }
     825             :         }
     826         237 :         return sub_function(result, op1, op2);
     827             : }
     828             : 
     829             : static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *op2)
     830             : {
     831      444819 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     832      444372 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     833             :                         zend_long overflow;
     834             : 
     835      443755 :                         ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
     836      443755 :                         Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
     837      443755 :                         return SUCCESS;
     838         617 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     839         614 :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
     840         614 :                         return SUCCESS;
     841             :                 }
     842         447 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     843         217 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     844         170 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
     845         170 :                         return SUCCESS;
     846          47 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     847          47 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
     848          47 :                         return SUCCESS;
     849             :                 }
     850             :         }
     851         233 :         return mul_function(result, op1, op2);
     852             : }
     853             : 
     854             : static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2)
     855             : {
     856             : #if 0
     857             :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && 0) {
     858             :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     859             :                         if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
     860             :                                 zend_error(E_WARNING, "Division by zero");
     861             :                                 ZVAL_BOOL(result, 0);
     862             :                                 return FAILURE;
     863             :                         } else if (UNEXPECTED(Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
     864             :                                 /* Prevent overflow error/crash */
     865             :                                 ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
     866             :                         } else if (EXPECTED(Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0)) {
     867             :                                 /* integer */
     868             :                                 ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
     869             :                         } else {
     870             :                                 ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / ((double)Z_LVAL_P(op2)));
     871             :                         }
     872             :                         return SUCCESS;
     873             :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     874             :                         if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
     875             :                                 zend_error(E_WARNING, "Division by zero");
     876             :                                 ZVAL_BOOL(result, 0);
     877             :                                 return FAILURE;
     878             :                         }
     879             :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) / Z_DVAL_P(op2));
     880             :                         return SUCCESS;
     881             :                 }
     882             :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE) && 0) {
     883             :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     884             :                         if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
     885             :                                 zend_error(E_WARNING, "Division by zero");
     886             :                                 ZVAL_BOOL(result, 0);
     887             :                                 return FAILURE;
     888             :                         }
     889             :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
     890             :                         return SUCCESS;
     891             :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     892             :                         if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
     893             :                                 zend_error(E_WARNING, "Division by zero");
     894             :                                 ZVAL_BOOL(result, 0);
     895             :                                 return FAILURE;
     896             :                         }
     897             :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) / ((double)Z_LVAL_P(op2)));
     898             :                         return SUCCESS;
     899             :                 }
     900             :         }
     901             : #endif
     902      125506 :         return div_function(result, op1, op2);
     903             : }
     904             : 
     905             : static zend_always_inline int fast_mod_function(zval *result, zval *op1, zval *op2)
     906             : {
     907       70488 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     908       70167 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     909       70148 :                         if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
     910          13 :                                 zend_error(E_WARNING, "Division by zero");
     911          13 :                                 ZVAL_FALSE(result);
     912          13 :                                 return FAILURE;
     913       70135 :                         } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
     914             :                                 /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
     915          13 :                                 ZVAL_LONG(result, 0);
     916          13 :                                 return SUCCESS;
     917             :                         }
     918       70122 :                         ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
     919       70122 :                         return SUCCESS;
     920             :                 }
     921             :         }
     922         340 :         return mod_function(result, op1, op2);
     923             : }
     924             : 
     925             : static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2)
     926             : {
     927             :         zval result;
     928       14577 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     929          21 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     930           0 :                         return Z_LVAL_P(op1) == Z_LVAL_P(op2);
     931          21 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     932           0 :                         return ((double)Z_LVAL_P(op1)) == Z_DVAL_P(op2);
     933             :                 }
     934       14556 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     935         316 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     936          16 :                         return Z_DVAL_P(op1) == Z_DVAL_P(op2);
     937         300 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     938         128 :                         return Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2));
     939             :                 }
     940       14240 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
     941          35 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
     942          25 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
     943           0 :                                 return 1;
     944          25 :                         } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
     945           9 :                                 if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
     946           8 :                                         return 0;
     947             :                                 } else {
     948           1 :                                         return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
     949             :                                 }
     950             :                         } else {
     951          16 :                                 return zendi_smart_strcmp(op1, op2) == 0;
     952             :                         }
     953             :                 }
     954             :         }
     955       14408 :         compare_function(&result, op1, op2);
     956       14408 :         return Z_LVAL(result) == 0;
     957             : }
     958             : 
     959             : static zend_always_inline int fast_equal_check_long(zval *op1, zval *op2)
     960             : {
     961             :         zval result;
     962        8066 :         if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     963        7865 :                 return Z_LVAL_P(op1) == Z_LVAL_P(op2);
     964             :         }
     965         201 :         compare_function(&result, op1, op2);
     966         201 :         return Z_LVAL(result) == 0;
     967             : }
     968             : 
     969             : static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2)
     970             : {
     971             :         zval result;
     972      477072 :         if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
     973      476421 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
     974          46 :                         return 1;
     975      476375 :                 } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
     976      472517 :                         if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
     977      431119 :                                 return 0;
     978             :                         } else {
     979       41398 :                                 return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
     980             :                         }
     981             :                 } else {
     982        3858 :                         return zendi_smart_strcmp(op1, op2) == 0;
     983             :                 }
     984             :         }
     985         651 :         compare_function(&result, op1, op2);
     986         651 :         return Z_LVAL(result) == 0;
     987             : }
     988             : 
     989             : static zend_always_inline void fast_equal_function(zval *result, zval *op1, zval *op2)
     990             : {
     991     2495925 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     992     1307048 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     993     1305737 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) == Z_LVAL_P(op2));
     994             :                         return;
     995        1311 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     996          17 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
     997             :                         return;
     998             :                 }
     999     1188877 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
    1000          89 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
    1001          43 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) == Z_DVAL_P(op2));
    1002             :                         return;
    1003          46 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1004          12 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
    1005             :                         return;
    1006             :                 }
    1007     1188788 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
    1008     1096029 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1009     1095921 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1010        1208 :                                 ZVAL_TRUE(result);
    1011             :                                 return;
    1012     1094713 :                         } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
    1013      954366 :                                 if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
    1014      434606 :                                         ZVAL_FALSE(result);
    1015             :                                         return;
    1016             :                                 } else {
    1017      519760 :                                         ZVAL_BOOL(result, memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
    1018             :                                         return;
    1019             :                                 }
    1020             :                         } else {
    1021      140347 :                                 ZVAL_BOOL(result, zendi_smart_strcmp(op1, op2) == 0);
    1022             :                                 return;
    1023             :                         }
    1024             :                 }
    1025             :         }
    1026       94195 :         compare_function(result, op1, op2);
    1027       94194 :         ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
    1028             : }
    1029             : 
    1030             : static zend_always_inline void fast_not_equal_function(zval *result, zval *op1, zval *op2)
    1031             : {
    1032      485279 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
    1033      108884 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1034      107243 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) != Z_LVAL_P(op2));
    1035             :                         return;
    1036        1641 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
    1037          20 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
    1038             :                         return;
    1039             :                 }
    1040      376395 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
    1041         128 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
    1042          13 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) != Z_DVAL_P(op2));
    1043             :                         return;
    1044         115 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1045           0 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
    1046             :                         return;
    1047             :                 }
    1048      376267 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
    1049      182864 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
    1050      179727 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
    1051         112 :                                 ZVAL_FALSE(result);
    1052             :                                 return;
    1053      179615 :                         } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
    1054       33583 :                                 if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
    1055       13895 :                                         ZVAL_TRUE(result);
    1056             :                                         return;
    1057             :                                 } else {
    1058       19688 :                                         ZVAL_BOOL(result, memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
    1059             :                                         return;
    1060             :                                 }
    1061             :                         } else {
    1062      146032 :                                 ZVAL_BOOL(result, zendi_smart_strcmp(op1, op2) != 0);
    1063             :                                 return;
    1064             :                         }
    1065             :                 }
    1066             :         }
    1067      198276 :         compare_function(result, op1, op2);
    1068      198276 :         ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
    1069             : }
    1070             : 
    1071             : static zend_always_inline void fast_is_smaller_function(zval *result, zval *op1, zval *op2)
    1072             : {
    1073     7008133 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
    1074     6545555 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1075     6309163 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) < Z_LVAL_P(op2));
    1076             :                         return;
    1077      236392 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
    1078      141055 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
    1079             :                         return;
    1080             :                 }
    1081      462578 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
    1082      113431 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
    1083         190 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) < Z_DVAL_P(op2));
    1084             :                         return;
    1085      113241 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1086      113207 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
    1087             :                         return;
    1088             :                 }
    1089             :         }
    1090      444518 :         compare_function(result, op1, op2);
    1091      444518 :         ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
    1092             : }
    1093             : 
    1094             : static zend_always_inline void fast_is_smaller_or_equal_function(zval *result, zval *op1, zval *op2)
    1095             : {
    1096      578731 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
    1097      478087 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1098      462090 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) <= Z_LVAL_P(op2));
    1099             :                         return;
    1100       15997 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
    1101       15889 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
    1102             :                         return;
    1103             :                 }
    1104      100644 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
    1105          86 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
    1106          19 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) <= Z_DVAL_P(op2));
    1107             :                         return;
    1108          67 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
    1109          25 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
    1110             :                         return;
    1111             :                 }
    1112             :         }
    1113      100708 :         compare_function(result, op1, op2);
    1114      100708 :         ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
    1115             : }
    1116             : 
    1117             : static zend_always_inline void fast_is_identical_function(zval *result, zval *op1, zval *op2)
    1118             : {
    1119     3415196 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    1120     2395136 :                 ZVAL_FALSE(result);
    1121             :                 return;
    1122             :         }
    1123     1020060 :         is_identical_function(result, op1, op2);
    1124             : }
    1125             : 
    1126             : static zend_always_inline void fast_is_not_identical_function(zval *result, zval *op1, zval *op2)
    1127             : {
    1128      548036 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
    1129      489314 :                 ZVAL_TRUE(result);
    1130             :                 return;
    1131             :         }
    1132       58722 :         is_identical_function(result, op1, op2);
    1133       58722 :         ZVAL_BOOL(result, Z_TYPE_P(result) != IS_TRUE);
    1134             : }
    1135             : 
    1136             : #define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op)                                            \
    1137             :         if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                             \
    1138             :                 && op1 == result                                                                                   \
    1139             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, get))                                                           \
    1140             :                 && EXPECTED(Z_OBJ_HANDLER_P(op1, set))) {                                                          \
    1141             :                 int ret;                                                                                           \
    1142             :                 zval rv;                                                                                           \
    1143             :                 zval *objval = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);                                      \
    1144             :                 Z_ADDREF_P(objval);                                                                                \
    1145             :                 ret = binary_op(objval, objval, op2);                                                    \
    1146             :                 Z_OBJ_HANDLER_P(op1, set)(op1, objval);                                                  \
    1147             :                 zval_ptr_dtor(objval);                                                                             \
    1148             :                 return ret;                                                                                        \
    1149             :         } else if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                      \
    1150             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))) {                                               \
    1151             :                 if (EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2))) { \
    1152             :                         return SUCCESS;                                                                                \
    1153             :                 }                                                                                                  \
    1154             :         }
    1155             : 
    1156             : #define ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)                                                       \
    1157             :         if (UNEXPECTED(Z_TYPE_P(op2) == IS_OBJECT)                                                             \
    1158             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op2, do_operation))                                                  \
    1159             :                 && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2))) {  \
    1160             :                 return SUCCESS;                                                                                    \
    1161             :         }
    1162             : 
    1163             : #define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode, binary_op)                                                \
    1164             :         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op)                                                \
    1165             :         else                                                                                                   \
    1166             :         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)
    1167             : 
    1168             : #define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode)                                                            \
    1169             :         if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                             \
    1170             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))                                                  \
    1171             :                 && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL))) { \
    1172             :                 return SUCCESS;                                                                                    \
    1173             :         }
    1174             : 
    1175             : /* buf points to the END of the buffer */
    1176             : static zend_always_inline char *zend_print_ulong_to_buf(char *buf, zend_ulong num) {
    1177     1278458 :         *buf = '\0';
    1178             :         do {
    1179     2180088 :                 *--buf = (char) (num % 10) + '0';
    1180     2180088 :                 num /= 10;
    1181     2180088 :         } while (num > 0);
    1182     1278458 :         return buf;
    1183             : }
    1184             : 
    1185             : /* buf points to the END of the buffer */
    1186             : static zend_always_inline char *zend_print_long_to_buf(char *buf, zend_long num) {
    1187      893340 :         if (num < 0) {
    1188        8354 :             char *result = zend_print_ulong_to_buf(buf, ~((zend_ulong) num) + 1);
    1189        4177 :             *--result = '-';
    1190        4177 :                 return result;
    1191             :         } else {
    1192     1778326 :             return zend_print_ulong_to_buf(buf, num);
    1193             :         }
    1194             : }
    1195             : 
    1196             : ZEND_API zend_string *zend_long_to_str(zend_long num);
    1197             : 
    1198             : END_EXTERN_C()
    1199             : 
    1200             : #endif
    1201             : 
    1202             : /*
    1203             :  * Local variables:
    1204             :  * tab-width: 4
    1205             :  * c-basic-offset: 4
    1206             :  * indent-tabs-mode: t
    1207             :  * End:
    1208             :  */

Generated by: LCOV version 1.10

Generated at Thu, 30 Apr 2015 23:09:59 +0000 (5 days ago)

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