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: 144 150 96.0 %
Date: 2015-06-27 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 ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2);
      48             : ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2);
      49             : ZEND_API int ZEND_FASTCALL mul_function(zval *result, zval *op1, zval *op2);
      50             : ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2);
      51             : ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2);
      52             : ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2);
      53             : ZEND_API int ZEND_FASTCALL boolean_xor_function(zval *result, zval *op1, zval *op2);
      54             : ZEND_API int ZEND_FASTCALL boolean_not_function(zval *result, zval *op1);
      55             : ZEND_API int ZEND_FASTCALL bitwise_not_function(zval *result, zval *op1);
      56             : ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op2);
      57             : ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *op2);
      58             : ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *op2);
      59             : ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op2);
      60             : ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *op2);
      61             : ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2);
      62             : 
      63             : ZEND_API int ZEND_FASTCALL zend_is_identical(zval *op1, zval *op2);
      64             : 
      65             : ZEND_API int ZEND_FASTCALL is_equal_function(zval *result, zval *op1, zval *op2);
      66             : ZEND_API int ZEND_FASTCALL is_identical_function(zval *result, zval *op1, zval *op2);
      67             : ZEND_API int ZEND_FASTCALL is_not_identical_function(zval *result, zval *op1, zval *op2);
      68             : ZEND_API int ZEND_FASTCALL is_not_equal_function(zval *result, zval *op1, zval *op2);
      69             : ZEND_API int ZEND_FASTCALL is_smaller_function(zval *result, zval *op1, zval *op2);
      70             : ZEND_API int ZEND_FASTCALL is_smaller_or_equal_function(zval *result, zval *op1, zval *op2);
      71             : 
      72             : ZEND_API zend_bool ZEND_FASTCALL instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only);
      73             : ZEND_API zend_bool ZEND_FASTCALL instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce);
      74             : 
      75             : /**
      76             :  * Checks whether the string "str" with length "length" is numeric. The value
      77             :  * of allow_errors determines whether it's required to be entirely numeric, or
      78             :  * just its prefix. Leading whitespace is allowed.
      79             :  *
      80             :  * The function returns 0 if the string did not contain a valid number; IS_LONG
      81             :  * if it contained a number that fits within the range of a long; or IS_DOUBLE
      82             :  * if the number was out of long range or contained a decimal point/exponent.
      83             :  * The number's value is returned into the respective pointer, *lval or *dval,
      84             :  * if that pointer is not NULL.
      85             :  *
      86             :  * This variant also gives information if a string that represents an integer
      87             :  * could not be represented as such due to overflow. It writes 1 to oflow_info
      88             :  * if the integer is larger than ZEND_LONG_MAX and -1 if it's smaller than ZEND_LONG_MIN.
      89             :  */
      90             : ZEND_API zend_uchar ZEND_FASTCALL _is_numeric_string_ex(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors, int *oflow_info);
      91             : 
      92             : ZEND_API const char* ZEND_FASTCALL zend_memnstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end);
      93             : ZEND_API const char* ZEND_FASTCALL zend_memnrstr_ex(const char *haystack, const char *needle, size_t needle_len, char *end);
      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             : #else
     112             : ZEND_API zend_long ZEND_FASTCALL zend_dval_to_lval_slow(double d);
     113             : 
     114             : static zend_always_inline zend_long zend_dval_to_lval(double d)
     115             : {
     116       28123 :         if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
     117           3 :                 return 0;
     118       28120 :         } else if (!ZEND_DOUBLE_FITS_LONG(d)) {
     119         140 :                 return zend_dval_to_lval_slow(d);
     120             :         }
     121       27980 :         return (zend_long)d;
     122             : }
     123             : #endif
     124             : /* }}} */
     125             : 
     126             : #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
     127             : #define ZEND_IS_XDIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
     128             : 
     129             : 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)
     130             : {
     131     1100269 :         if (*str > '9') {
     132      136738 :                 return 0;
     133             :         }
     134      963531 :         return _is_numeric_string_ex(str, length, lval, dval, allow_errors, oflow_info);
     135             : }
     136             : 
     137             : static zend_always_inline zend_uchar is_numeric_string(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors) {
     138      158063 :     return is_numeric_string_ex(str, length, lval, dval, allow_errors, NULL);
     139             : }
     140             : 
     141             : ZEND_API zend_uchar ZEND_FASTCALL is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval);
     142             : 
     143             : static zend_always_inline const char *
     144             : zend_memnstr(const char *haystack, const char *needle, size_t needle_len, char *end)
     145             : {
     146     2720672 :         const char *p = haystack;
     147     2720672 :         const char ne = needle[needle_len-1];
     148             :         ptrdiff_t off_p;
     149             :         size_t off_s;
     150             : 
     151     2720672 :         if (needle_len == 1) {
     152     1898591 :                 return (const char *)memchr(p, *needle, (end-p));
     153             :         }
     154             : 
     155      822081 :         off_p = end - haystack;
     156      822081 :         off_s = (off_p > 0) ? (size_t)off_p : 0;
     157             : 
     158      822081 :         if (needle_len > off_s) {
     159       10602 :                 return NULL;
     160             :         }
     161             : 
     162      811479 :         if (EXPECTED(off_s < 1024 || needle_len < 3)) {
     163      796544 :                 end -= needle_len;
     164             : 
     165     3564337 :                 while (p <= end) {
     166     3494559 :                         if ((p = (const char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
     167      523117 :                                 if (!memcmp(needle, p, needle_len-1)) {
     168      208966 :                                         return p;
     169             :                                 }
     170             :                         }
     171             : 
     172     3285593 :                         if (p == NULL) {
     173      517800 :                                 return NULL;
     174             :                         }
     175             : 
     176     2767793 :                         p++;
     177             :                 }
     178             : 
     179       69778 :                 return NULL;
     180             :         } else {
     181       14935 :                 return zend_memnstr_ex(haystack, needle, needle_len, end);
     182             :         }
     183             : }
     184             : 
     185             : static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t n)
     186             : {
     187             :         register const unsigned char *e;
     188     3507330 :         if (n <= 0) {
     189         443 :                 return NULL;
     190             :         }
     191             : 
     192    61677949 :         for (e = (const unsigned char *)s + n - 1; e >= (const unsigned char *)s; e--) {
     193    58208802 :                 if (*e == (const unsigned char)c) {
     194       37740 :                         return (const void *)e;
     195             :                 }
     196             :         }
     197     3469147 :         return NULL;
     198             : }
     199             : 
     200             : 
     201             : static zend_always_inline const char *
     202             : zend_memnrstr(const char *haystack, const char *needle, size_t needle_len, char *end)
     203             : {
     204         575 :     const char *p = end;
     205         575 :     const char ne = needle[needle_len-1];
     206             :     ptrdiff_t off_p;
     207             :     size_t off_s;
     208             : 
     209         575 :     if (needle_len == 1) {
     210         480 :         return (const char *)zend_memrchr(haystack, *needle, (p - haystack));
     211             :     }
     212             : 
     213         335 :     off_p = end - haystack;
     214         335 :     off_s = (off_p > 0) ? (size_t)off_p : 0;
     215             : 
     216         335 :     if (needle_len > off_s) {
     217          29 :         return NULL;
     218             :     }
     219             : 
     220         306 :         if (EXPECTED(off_s < 1024 || needle_len < 3)) {
     221         306 :                 p -= needle_len;
     222             : 
     223             :                 do {
     224        1180 :                         if ((p = (const char *)zend_memrchr(haystack, *needle, (p - haystack) + 1)) && ne == p[needle_len-1]) {
     225         236 :                                 if (!memcmp(needle, p, needle_len - 1)) {
     226         208 :                                         return p;
     227             :                                 }
     228             :                         }
     229         382 :                 } while (p-- >= haystack);
     230             : 
     231          98 :                 return NULL;
     232             :         } else {
     233           0 :                 return zend_memnrstr_ex(haystack, needle, needle_len, end);
     234             :         }
     235             : }
     236             : 
     237             : ZEND_API int ZEND_FASTCALL increment_function(zval *op1);
     238             : ZEND_API int ZEND_FASTCALL decrement_function(zval *op2);
     239             : 
     240             : ZEND_API void ZEND_FASTCALL convert_scalar_to_number(zval *op);
     241             : ZEND_API void ZEND_FASTCALL _convert_to_cstring(zval *op ZEND_FILE_LINE_DC);
     242             : ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op ZEND_FILE_LINE_DC);
     243             : ZEND_API void ZEND_FASTCALL convert_to_long(zval *op);
     244             : ZEND_API void ZEND_FASTCALL convert_to_double(zval *op);
     245             : ZEND_API void ZEND_FASTCALL convert_to_long_base(zval *op, int base);
     246             : ZEND_API void ZEND_FASTCALL convert_to_null(zval *op);
     247             : ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op);
     248             : ZEND_API void ZEND_FASTCALL convert_to_array(zval *op);
     249             : ZEND_API void ZEND_FASTCALL convert_to_object(zval *op);
     250             : ZEND_API void multi_convert_to_long_ex(int argc, ...);
     251             : ZEND_API void multi_convert_to_double_ex(int argc, ...);
     252             : ZEND_API void multi_convert_to_string_ex(int argc, ...);
     253             : 
     254             : ZEND_API zend_long    ZEND_FASTCALL _zval_get_long_func(zval *op);
     255             : ZEND_API double       ZEND_FASTCALL _zval_get_double_func(zval *op);
     256             : ZEND_API zend_string* ZEND_FASTCALL _zval_get_string_func(zval *op);
     257             : 
     258             : static zend_always_inline zend_long _zval_get_long(zval *op) {
     259      337772 :         return Z_TYPE_P(op) == IS_LONG ? Z_LVAL_P(op) : _zval_get_long_func(op);
     260             : }
     261             : static zend_always_inline double _zval_get_double(zval *op) {
     262      207414 :         return Z_TYPE_P(op) == IS_DOUBLE ? Z_DVAL_P(op) : _zval_get_double_func(op);
     263             : }
     264             : static zend_always_inline zend_string *_zval_get_string(zval *op) {
     265     6644588 :         return Z_TYPE_P(op) == IS_STRING ? zend_string_copy(Z_STR_P(op)) : _zval_get_string_func(op);
     266             : }
     267             : 
     268             : #define zval_get_long(op) _zval_get_long((op))
     269             : #define zval_get_double(op) _zval_get_double((op))
     270             : #define zval_get_string(op) _zval_get_string((op))
     271             : 
     272             : #define convert_to_cstring(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_cstring((op) ZEND_FILE_LINE_CC); }
     273             : #define convert_to_string(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
     274             : 
     275             : 
     276             : ZEND_API int ZEND_FASTCALL zend_is_true(zval *op);
     277             : ZEND_API int ZEND_FASTCALL zend_object_is_true(zval *op);
     278             : 
     279             : #define zval_is_true(op) \
     280             :         zend_is_true(op)
     281             : 
     282             : static zend_always_inline int i_zend_is_true(zval *op)
     283             : {
     284             :         int result;
     285             : 
     286             : again:
     287     2977041 :         switch (Z_TYPE_P(op)) {
     288             :                 case IS_UNDEF:
     289             :                 case IS_NULL:
     290             :                 case IS_FALSE:
     291      123173 :                         result = 0;
     292             :                         break;
     293             :                 case IS_TRUE:
     294      170057 :                         result = 1;
     295             :                         break;
     296             :                 case IS_LONG:
     297     2133750 :                         result = (Z_LVAL_P(op)?1:0);
     298             :                         break;
     299             :                 case IS_RESOURCE:
     300       42479 :                         result = (Z_RES_HANDLE_P(op)?1:0);
     301             :                         break;
     302             :                 case IS_DOUBLE:
     303         265 :                         result = (Z_DVAL_P(op) ? 1 : 0);
     304             :                         break;
     305             :                 case IS_STRING:
     306      239146 :                         if (Z_STRLEN_P(op) == 0
     307      143575 :                                 || (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
     308       48167 :                                 result = 0;
     309             :                         } else {
     310       47404 :                                 result = 1;
     311             :                         }
     312             :                         break;
     313             :                 case IS_ARRAY:
     314      101600 :                         result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
     315             :                         break;
     316             :                 case IS_OBJECT:
     317       92375 :                         result = zend_object_is_true(op);
     318             :                         break;
     319             :                 case IS_REFERENCE:
     320      217771 :                         op = Z_REFVAL_P(op);
     321             :                         goto again;
     322             :                         break;
     323             :                 default:
     324           0 :                         result = 0;
     325             :                         break;
     326             :         }
     327     2759269 :         return result;
     328             : }
     329             : 
     330             : ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2);
     331             : ZEND_API int zval_compare_function(zval *result, zval *op1, zval *op2);
     332             : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2);
     333             : ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive);
     334             : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2);
     335             : ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2);
     336             : #if HAVE_STRCOLL
     337             : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2);
     338             : #endif
     339             : 
     340             : ZEND_API void         ZEND_FASTCALL zend_str_tolower(char *str, size_t length);
     341             : ZEND_API char*        ZEND_FASTCALL zend_str_tolower_copy(char *dest, const char *source, size_t length);
     342             : ZEND_API char*        ZEND_FASTCALL zend_str_tolower_dup(const char *source, size_t length);
     343             : ZEND_API zend_string* ZEND_FASTCALL zend_string_tolower(zend_string *str);
     344             : 
     345             : ZEND_API int ZEND_FASTCALL zend_binary_zval_strcmp(zval *s1, zval *s2);
     346             : ZEND_API int ZEND_FASTCALL zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
     347             : ZEND_API int ZEND_FASTCALL zend_binary_zval_strcasecmp(zval *s1, zval *s2);
     348             : ZEND_API int ZEND_FASTCALL zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3);
     349             : ZEND_API int ZEND_FASTCALL zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2);
     350             : ZEND_API int ZEND_FASTCALL zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     351             : ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2);
     352             : ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     353             : ZEND_API int ZEND_FASTCALL zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2);
     354             : ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     355             : 
     356             : ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zval *s1, zval *s2);
     357             : ZEND_API int ZEND_FASTCALL zend_compare_symbol_tables(HashTable *ht1, HashTable *ht2);
     358             : ZEND_API int ZEND_FASTCALL zend_compare_arrays(zval *a1, zval *a2);
     359             : ZEND_API int ZEND_FASTCALL zend_compare_objects(zval *o1, zval *o2);
     360             : 
     361             : ZEND_API int ZEND_FASTCALL zend_atoi(const char *str, int str_len);
     362             : ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, int str_len);
     363             : 
     364             : ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
     365             : 
     366             : #define convert_to_ex_master(pzv, lower_type, upper_type)       \
     367             :         if (Z_TYPE_P(pzv)!=upper_type) {                                        \
     368             :                 convert_to_##lower_type(pzv);                                           \
     369             :         }
     370             : 
     371             : #define convert_to_explicit_type(pzv, type)             \
     372             :         do {                                                                            \
     373             :                 switch (type) {                                                 \
     374             :                         case IS_NULL:                                           \
     375             :                                 convert_to_null(pzv);                   \
     376             :                                 break;                                                  \
     377             :                         case IS_LONG:                                           \
     378             :                                 convert_to_long(pzv);                   \
     379             :                                 break;                                                  \
     380             :                         case IS_DOUBLE:                                         \
     381             :                                 convert_to_double(pzv);                 \
     382             :                                 break;                                                  \
     383             :                         case _IS_BOOL:                                          \
     384             :                                 convert_to_boolean(pzv);                \
     385             :                                 break;                                                  \
     386             :                         case IS_ARRAY:                                          \
     387             :                                 convert_to_array(pzv);                  \
     388             :                                 break;                                                  \
     389             :                         case IS_OBJECT:                                         \
     390             :                                 convert_to_object(pzv);                 \
     391             :                                 break;                                                  \
     392             :                         case IS_STRING:                                         \
     393             :                                 convert_to_string(pzv);                 \
     394             :                                 break;                                                  \
     395             :                         default:                                                        \
     396             :                                 assert(0);                                              \
     397             :                                 break;                                                  \
     398             :                 }                                                                               \
     399             :         } while (0);
     400             : 
     401             : #define convert_to_explicit_type_ex(pzv, str_type)      \
     402             :         if (Z_TYPE_P(pzv) != str_type) {                                \
     403             :                 convert_to_explicit_type(pzv, str_type);        \
     404             :         }
     405             : 
     406             : #define convert_to_boolean_ex(pzv)      convert_to_ex_master(pzv, boolean, _IS_BOOL)
     407             : #define convert_to_long_ex(pzv)         convert_to_ex_master(pzv, long, IS_LONG)
     408             : #define convert_to_double_ex(pzv)       convert_to_ex_master(pzv, double, IS_DOUBLE)
     409             : #define convert_to_string_ex(pzv)       convert_to_ex_master(pzv, string, IS_STRING)
     410             : #define convert_to_array_ex(pzv)        convert_to_ex_master(pzv, array, IS_ARRAY)
     411             : #define convert_to_object_ex(pzv)       convert_to_ex_master(pzv, object, IS_OBJECT)
     412             : #define convert_to_null_ex(pzv)         convert_to_ex_master(pzv, null, IS_NULL)
     413             : 
     414             : #define convert_scalar_to_number_ex(pzv)                                                        \
     415             :         if (Z_TYPE_P(pzv)!=IS_LONG && Z_TYPE_P(pzv)!=IS_DOUBLE) {               \
     416             :                 convert_scalar_to_number(pzv);                                  \
     417             :         }
     418             : 
     419             : #if HAVE_SETLOCALE && defined(ZEND_WIN32) && !defined(ZTS) && defined(_MSC_VER)
     420             : /* This performance improvement of tolower() on Windows gives 10-18% on bench.php */
     421             : #define ZEND_USE_TOLOWER_L 1
     422             : #endif
     423             : 
     424             : #ifdef ZEND_USE_TOLOWER_L
     425             : ZEND_API void zend_update_current_locale(void);
     426             : #else
     427             : #define zend_update_current_locale()
     428             : #endif
     429             : 
     430             : /* The offset in bytes between the value and type fields of a zval */
     431             : #define ZVAL_OFFSETOF_TYPE      \
     432             :         (offsetof(zval, u1.type_info) - offsetof(zval, value))
     433             : 
     434             : static zend_always_inline void fast_long_increment_function(zval *op1)
     435             : {
     436             : #if defined(__GNUC__) && defined(__i386__)
     437             :         __asm__(
     438             :                 "incl (%0)\n\t"
     439             :                 "jno  0f\n\t"
     440             :                 "movl $0x0, (%0)\n\t"
     441             :                 "movl $0x41e00000, 0x4(%0)\n\t"
     442             :                 "movl %1, %c2(%0)\n"
     443             :                 "0:"
     444             :                 :
     445             :                 : "r"(&op1->value),
     446             :                   "n"(IS_DOUBLE),
     447             :                   "n"(ZVAL_OFFSETOF_TYPE)
     448             :                 : "cc");
     449             : #elif defined(__GNUC__) && defined(__x86_64__)
     450     7483513 :         __asm__(
     451             :                 "incq (%0)\n\t"
     452             :                 "jno  0f\n\t"
     453             :                 "movl $0x0, (%0)\n\t"
     454             :                 "movl $0x43e00000, 0x4(%0)\n\t"
     455             :                 "movl %1, %c2(%0)\n"
     456             :                 "0:"
     457             :                 :
     458     7483513 :                 : "r"(&op1->value),
     459             :                   "n"(IS_DOUBLE),
     460             :                   "n"(ZVAL_OFFSETOF_TYPE)
     461             :                 : "cc");
     462             : #elif defined(__GNUC__) && defined(__powerpc64__)
     463             :          __asm__(
     464             :                 "ld 14, 0(%0)\n\t"
     465             :                 "li 15, 1\n\t"
     466             :                 "li 16, 0\n\t"
     467             :                 "mtxer 16\n\t"
     468             :                 "addo. 14, 14, 15\n\t"
     469             :                 "std 14, 0(%0)\n\t"
     470             :                 "bns+  0f\n\t"
     471             :                 "xor 14, 14, 14\n\t"
     472             :                 "lis 15, 0x43e00000@h\n\t"
     473             :                 "ori 15, 15, 0x43e00000@l\n\t"
     474             : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     475             :                 "stw 14, 0(%0)\n\t"
     476             :                 "stw 15, 0x4(%0)\n\t"
     477             : #else
     478             :                 "stw 14, 0x4(%0)\n\t"
     479             :                 "stw 15, 0(%0)\n\t"
     480             : #endif
     481             :                 "li 14, %1\n\t"
     482             :                 "stw 14, %c2(%0)\n"
     483             :                 "0:"
     484             :                 :
     485             :                 : "r"(&op1->value),
     486             :                   "n"(IS_DOUBLE),
     487             :                   "n"(ZVAL_OFFSETOF_TYPE)
     488             :                 : "r14", "r15", "r16", "cc");
     489             : #else
     490             :         if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
     491             :                 /* switch to double */
     492             :                 ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
     493             :         } else {
     494             :                 Z_LVAL_P(op1)++;
     495             :         }
     496             : #endif
     497             : }
     498             : 
     499             : static zend_always_inline void fast_long_decrement_function(zval *op1)
     500             : {
     501             : #if defined(__GNUC__) && defined(__i386__)
     502             :         __asm__(
     503             :                 "decl (%0)\n\t"
     504             :                 "jno  0f\n\t"
     505             :                 "movl $0x00200000, (%0)\n\t"
     506             :                 "movl $0xc1e00000, 0x4(%0)\n\t"
     507             :                 "movl %1,%c2(%0)\n"
     508             :                 "0:"
     509             :                 :
     510             :                 : "r"(&op1->value),
     511             :                   "n"(IS_DOUBLE),
     512             :                   "n"(ZVAL_OFFSETOF_TYPE)
     513             :                 : "cc");
     514             : #elif defined(__GNUC__) && defined(__x86_64__)
     515      451821 :         __asm__(
     516             :                 "decq (%0)\n\t"
     517             :                 "jno  0f\n\t"
     518             :                 "movl $0x00000000, (%0)\n\t"
     519             :                 "movl $0xc3e00000, 0x4(%0)\n\t"
     520             :                 "movl %1,%c2(%0)\n"
     521             :                 "0:"
     522             :                 :
     523      451821 :                 : "r"(&op1->value),
     524             :                   "n"(IS_DOUBLE),
     525             :                   "n"(ZVAL_OFFSETOF_TYPE)
     526             :                 : "cc");
     527             : #elif defined(__GNUC__) && defined(__powerpc64__)
     528             :         __asm__(
     529             :                 "ld 14, 0(%0)\n\t"
     530             :                 "li 15, 1\n\t"
     531             :                 "li 16, 0\n\t"
     532             :                 "mtxer 16\n\t"
     533             :                 "subo. 14, 14, 15\n\t"
     534             :                 "std 14, 0(%0)\n\t"
     535             :                 "bns+  0f\n\t"
     536             :                 "xor 14, 14, 14\n\t"
     537             :                 "lis 15, 0xc3e00000@h\n\t"
     538             :                 "ori 15, 15, 0xc3e00000@l\n\t"
     539             : #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     540             :                 "stw 14, 0(%0)\n\t"
     541             :                 "stw 15, 0x4(%0)\n\t"
     542             : #else
     543             :                 "stw 14, 0x4(%0)\n\t"
     544             :                 "stw 15, 0(%0)\n\t"
     545             : #endif
     546             :                 "li 14, %1\n\t"
     547             :                 "stw 14, %c2(%0)\n"
     548             :                 "0:"
     549             :                 :
     550             :                 : "r"(&op1->value),
     551             :                   "n"(IS_DOUBLE),
     552             :                   "n"(ZVAL_OFFSETOF_TYPE)
     553             :                 : "r14", "r15", "r16", "cc");
     554             : #else
     555             :         if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
     556             :                 /* switch to double */
     557             :                 ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
     558             :         } else {
     559             :                 Z_LVAL_P(op1)--;
     560             :         }
     561             : #endif
     562             : }
     563             : 
     564             : static zend_always_inline void fast_long_add_function(zval *result, zval *op1, zval *op2)
     565             : {
     566             : #if defined(__GNUC__) && defined(__i386__)
     567             :         __asm__(
     568             :                 "movl      (%1), %%eax\n\t"
     569             :                 "addl   (%2), %%eax\n\t"
     570             :                 "jo     0f\n\t"
     571             :                 "movl   %%eax, (%0)\n\t"
     572             :                 "movl   %3, %c5(%0)\n\t"
     573             :                 "jmp    1f\n"
     574             :                 "0:\n\t"
     575             :                 "fildl     (%1)\n\t"
     576             :                 "fildl     (%2)\n\t"
     577             :                 "faddp     %%st, %%st(1)\n\t"
     578             :                 "movl   %4, %c5(%0)\n\t"
     579             :                 "fstpl     (%0)\n"
     580             :                 "1:"
     581             :                 :
     582             :                 : "r"(&result->value),
     583             :                   "r"(&op1->value),
     584             :                   "r"(&op2->value),
     585             :                   "n"(IS_LONG),
     586             :                   "n"(IS_DOUBLE),
     587             :                   "n"(ZVAL_OFFSETOF_TYPE)
     588             :                 : "eax","cc");
     589             : #elif defined(__GNUC__) && defined(__x86_64__)
     590      779663 :         __asm__(
     591             :                 "movq      (%1), %%rax\n\t"
     592             :                 "addq   (%2), %%rax\n\t"
     593             :                 "jo     0f\n\t"
     594             :                 "movq   %%rax, (%0)\n\t"
     595             :                 "movl   %3, %c5(%0)\n\t"
     596             :                 "jmp    1f\n"
     597             :                 "0:\n\t"
     598             :                 "fildq     (%1)\n\t"
     599             :                 "fildq     (%2)\n\t"
     600             :                 "faddp     %%st, %%st(1)\n\t"
     601             :                 "movl   %4, %c5(%0)\n\t"
     602             :                 "fstpl     (%0)\n"
     603             :                 "1:"
     604             :                 :
     605      779663 :                 : "r"(&result->value),
     606      779663 :                   "r"(&op1->value),
     607      779663 :                   "r"(&op2->value),
     608             :                   "n"(IS_LONG),
     609             :                   "n"(IS_DOUBLE),
     610             :                   "n"(ZVAL_OFFSETOF_TYPE)
     611             :                 : "rax","cc");
     612             : #elif defined(__GNUC__) && defined(__powerpc64__)
     613             :         __asm__(
     614             :                 "ld 14, 0(%1)\n\t"
     615             :                 "ld 15, 0(%2)\n\t"
     616             :                 "li 16, 0 \n\t"
     617             :                 "mtxer 16\n\t"
     618             :                 "addo. 14, 14, 15\n\t"
     619             :                 "bso- 0f\n\t"
     620             :                 "std 14, 0(%0)\n\t"
     621             :                 "li 14, %3\n\t"
     622             :                 "stw 14, %c5(%0)\n\t"
     623             :                 "b 1f\n"
     624             :                 "0:\n\t"
     625             :                 "lfd 0, 0(%1)\n\t"
     626             :                 "lfd 1, 0(%2)\n\t"
     627             :                 "fcfid 0, 0\n\t"
     628             :                 "fcfid 1, 1\n\t"
     629             :                 "fadd 0, 0, 1\n\t"
     630             :                 "li 14, %4\n\t"
     631             :                 "stw 14, %c5(%0)\n\t"
     632             :                 "stfd 0, 0(%0)\n"
     633             :                 "1:"
     634             :                 :
     635             :                 : "r"(&result->value),
     636             :                   "r"(&op1->value),
     637             :                   "r"(&op2->value),
     638             :                   "n"(IS_LONG),
     639             :                   "n"(IS_DOUBLE),
     640             :                   "n"(ZVAL_OFFSETOF_TYPE)
     641             :                 : "r14","r15","r16","fr0","fr1","cc");
     642             : #else
     643             :         /*
     644             :          * 'result' may alias with op1 or op2, so we need to
     645             :          * ensure that 'result' is not updated until after we
     646             :          * have read the values of op1 and op2.
     647             :          */
     648             : 
     649             :         if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     650             :                 && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
     651             :                 ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
     652             :         } else {
     653             :                 ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
     654             :         }
     655             : #endif
     656             : }
     657             : 
     658             : static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2)
     659             : {
     660      202150 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     661      202106 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     662             :                         fast_long_add_function(result, op1, op2);
     663      202097 :                         return SUCCESS;
     664           9 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     665           9 :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     666           9 :                         return SUCCESS;
     667             :                 }
     668          44 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     669          44 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     670          35 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     671          35 :                         return SUCCESS;
     672           9 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     673           9 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     674           9 :                         return SUCCESS;
     675             :                 }
     676             :         }
     677           0 :         return add_function(result, op1, op2);
     678             : }
     679             : 
     680             : static zend_always_inline void fast_long_sub_function(zval *result, zval *op1, zval *op2)
     681             : {
     682             : #if defined(__GNUC__) && defined(__i386__)
     683             :         __asm__(
     684             :                 "movl      (%1), %%eax\n\t"
     685             :                 "subl   (%2), %%eax\n\t"
     686             :                 "jo     0f\n\t"
     687             :                 "movl   %%eax, (%0)\n\t"
     688             :                 "movl   %3, %c5(%0)\n\t"
     689             :                 "jmp    1f\n"
     690             :                 "0:\n\t"
     691             :                 "fildl     (%2)\n\t"
     692             :                 "fildl     (%1)\n\t"
     693             : #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
     694             :                 "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
     695             : #else
     696             :                 "fsubp     %%st, %%st(1)\n\t"
     697             : #endif
     698             :                 "movl   %4, %c5(%0)\n\t"
     699             :                 "fstpl     (%0)\n"
     700             :                 "1:"
     701             :                 :
     702             :                 : "r"(&result->value),
     703             :                   "r"(&op1->value),
     704             :                   "r"(&op2->value),
     705             :                   "n"(IS_LONG),
     706             :                   "n"(IS_DOUBLE),
     707             :                   "n"(ZVAL_OFFSETOF_TYPE)
     708             :                 : "eax","cc");
     709             : #elif defined(__GNUC__) && defined(__x86_64__)
     710      329263 :         __asm__(
     711             :                 "movq      (%1), %%rax\n\t"
     712             :                 "subq   (%2), %%rax\n\t"
     713             :                 "jo     0f\n\t"
     714             :                 "movq   %%rax, (%0)\n\t"
     715             :                 "movl   %3, %c5(%0)\n\t"
     716             :                 "jmp    1f\n"
     717             :                 "0:\n\t"
     718             :                 "fildq     (%2)\n\t"
     719             :                 "fildq     (%1)\n\t"
     720             : #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
     721             :                 "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
     722             : #else
     723             :                 "fsubp     %%st, %%st(1)\n\t"
     724             : #endif
     725             :                 "movl   %4, %c5(%0)\n\t"
     726             :                 "fstpl     (%0)\n"
     727             :                 "1:"
     728             :                 :
     729      329263 :                 : "r"(&result->value),
     730      329263 :                   "r"(&op1->value),
     731      329263 :                   "r"(&op2->value),
     732             :                   "n"(IS_LONG),
     733             :                   "n"(IS_DOUBLE),
     734             :                   "n"(ZVAL_OFFSETOF_TYPE)
     735             :                 : "rax","cc");
     736             : #elif defined(__GNUC__) && defined(__powerpc64__)
     737             :         __asm__(
     738             :                 "ld 14, 0(%1)\n\t"
     739             :                 "ld 15, 0(%2)\n\t"
     740             :                 "li 16, 0\n\t"
     741             :                 "mtxer 16\n\t"
     742             :                 "subo. 14, 14, 15\n\t"
     743             :                 "bso- 0f\n\t"
     744             :                 "std 14, 0(%0)\n\t"
     745             :                 "li 14, %3\n\t"
     746             :                 "stw 14, %c5(%0)\n\t"
     747             :                 "b 1f\n"
     748             :                 "0:\n\t"
     749             :                 "lfd 0, 0(%1)\n\t"
     750             :                 "lfd 1, 0(%2)\n\t"
     751             :                 "fcfid 0, 0\n\t"
     752             :                 "fcfid 1, 1\n\t"
     753             :                 "fsub 0, 0, 1\n\t"
     754             :                 "li 14, %4\n\t"
     755             :                 "stw 14, %c5(%0)\n\t"
     756             :                 "stfd 0, 0(%0)\n"
     757             :                 "1:"
     758             :                 :
     759             :                 : "r"(&result->value),
     760             :                   "r"(&op1->value),
     761             :                   "r"(&op2->value),
     762             :                   "n"(IS_LONG),
     763             :                   "n"(IS_DOUBLE),
     764             :                   "n"(ZVAL_OFFSETOF_TYPE)
     765             :                 : "r14","r15","r16","fr0","fr1","cc");
     766             : #else
     767             :         ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
     768             : 
     769             :         if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     770             :                 && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
     771             :                 ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
     772             :         }
     773             : #endif
     774             : }
     775             : 
     776             : static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2)
     777             : {
     778      163423 :         return div_function(result, op1, op2);
     779             : }
     780             : 
     781             : static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2)
     782             : {
     783             :         zval result;
     784       14403 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     785          21 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     786           0 :                         return Z_LVAL_P(op1) == Z_LVAL_P(op2);
     787          21 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     788           0 :                         return ((double)Z_LVAL_P(op1)) == Z_DVAL_P(op2);
     789             :                 }
     790       14382 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     791         316 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     792          16 :                         return Z_DVAL_P(op1) == Z_DVAL_P(op2);
     793         300 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     794         128 :                         return Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2));
     795             :                 }
     796       14066 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
     797          35 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
     798          25 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
     799           0 :                                 return 1;
     800          25 :                         } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
     801           9 :                                 if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
     802           8 :                                         return 0;
     803             :                                 } else {
     804           1 :                                         return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
     805             :                                 }
     806             :                         } else {
     807          16 :                                 return zendi_smart_strcmp(op1, op2) == 0;
     808             :                         }
     809             :                 }
     810             :         }
     811       14234 :         compare_function(&result, op1, op2);
     812       14234 :         return Z_LVAL(result) == 0;
     813             : }
     814             : 
     815             : static zend_always_inline int fast_equal_check_long(zval *op1, zval *op2)
     816             : {
     817             :         zval result;
     818        8063 :         if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     819        7862 :                 return Z_LVAL_P(op1) == Z_LVAL_P(op2);
     820             :         }
     821         201 :         compare_function(&result, op1, op2);
     822         201 :         return Z_LVAL(result) == 0;
     823             : }
     824             : 
     825             : static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2)
     826             : {
     827             :         zval result;
     828      477479 :         if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
     829      476828 :                 if (Z_STR_P(op1) == Z_STR_P(op2)) {
     830          46 :                         return 1;
     831      476782 :                 } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
     832      472870 :                         if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
     833      431426 :                                 return 0;
     834             :                         } else {
     835       41444 :                                 return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
     836             :                         }
     837             :                 } else {
     838        3912 :                         return zendi_smart_strcmp(op1, op2) == 0;
     839             :                 }
     840             :         }
     841         651 :         compare_function(&result, op1, op2);
     842         651 :         return Z_LVAL(result) == 0;
     843             : }
     844             : 
     845             : static zend_always_inline int fast_is_identical_function(zval *op1, zval *op2)
     846             : {
     847     3414088 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
     848     2398428 :                 return 0;
     849     1015660 :         } else if (Z_TYPE_P(op1) <= IS_TRUE) {
     850       37325 :                 return 1;
     851             :         }
     852      978335 :         return zend_is_identical(op1, op2);
     853             : }
     854             : 
     855             : static zend_always_inline int fast_is_not_identical_function(zval *op1, zval *op2)
     856             : {
     857      556352 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
     858      497006 :                 return 1;
     859       59346 :         } else if (Z_TYPE_P(op1) <= IS_TRUE) {
     860       18964 :                 return 0;
     861             :         }
     862       40382 :         return !zend_is_identical(op1, op2);
     863             : }
     864             : 
     865             : #define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op)                                            \
     866             :         if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                             \
     867             :                 && op1 == result                                                                                   \
     868             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, get))                                                           \
     869             :                 && EXPECTED(Z_OBJ_HANDLER_P(op1, set))) {                                                          \
     870             :                 int ret;                                                                                           \
     871             :                 zval rv;                                                                                           \
     872             :                 zval *objval = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);                                      \
     873             :                 Z_ADDREF_P(objval);                                                                                \
     874             :                 ret = binary_op(objval, objval, op2);                                                    \
     875             :                 Z_OBJ_HANDLER_P(op1, set)(op1, objval);                                                  \
     876             :                 zval_ptr_dtor(objval);                                                                             \
     877             :                 return ret;                                                                                        \
     878             :         } else if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                      \
     879             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))) {                                               \
     880             :                 if (EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2))) { \
     881             :                         return SUCCESS;                                                                                \
     882             :                 }                                                                                                  \
     883             :         }
     884             : 
     885             : #define ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)                                                       \
     886             :         if (UNEXPECTED(Z_TYPE_P(op2) == IS_OBJECT)                                                             \
     887             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op2, do_operation))                                                  \
     888             :                 && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2))) {  \
     889             :                 return SUCCESS;                                                                                    \
     890             :         }
     891             : 
     892             : #define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode, binary_op)                                                \
     893             :         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op)                                                \
     894             :         else                                                                                                   \
     895             :         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)
     896             : 
     897             : #define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode)                                                            \
     898             :         if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                             \
     899             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))                                                  \
     900             :                 && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL))) { \
     901             :                 return SUCCESS;                                                                                    \
     902             :         }
     903             : 
     904             : /* buf points to the END of the buffer */
     905             : static zend_always_inline char *zend_print_ulong_to_buf(char *buf, zend_ulong num) {
     906     1322059 :         *buf = '\0';
     907             :         do {
     908     2287485 :                 *--buf = (char) (num % 10) + '0';
     909     2287485 :                 num /= 10;
     910     2287485 :         } while (num > 0);
     911     1322059 :         return buf;
     912             : }
     913             : 
     914             : /* buf points to the END of the buffer */
     915             : static zend_always_inline char *zend_print_long_to_buf(char *buf, zend_long num) {
     916      916921 :         if (num < 0) {
     917        8290 :             char *result = zend_print_ulong_to_buf(buf, ~((zend_ulong) num) + 1);
     918        4145 :             *--result = '-';
     919        4145 :                 return result;
     920             :         } else {
     921     1825552 :             return zend_print_ulong_to_buf(buf, num);
     922             :         }
     923             : }
     924             : 
     925             : ZEND_API zend_string* ZEND_FASTCALL zend_long_to_str(zend_long num);
     926             : 
     927             : END_EXTERN_C()
     928             : 
     929             : #endif
     930             : 
     931             : /*
     932             :  * Local variables:
     933             :  * tab-width: 4
     934             :  * c-basic-offset: 4
     935             :  * indent-tabs-mode: t
     936             :  * End:
     937             :  */

Generated by: LCOV version 1.10

Generated at Sat, 27 Jun 2015 09:41:06 +0000 (7 days ago)

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