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: 218 221 98.6 %
Date: 2014-11-22 Functions: 0 0 -
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 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 TSRMLS_DC);
      48             : ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      49             : ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      50             : ZEND_API int pow_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      51             : ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      52             : ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      53             : ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      54             : ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC);
      55             : ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC);
      56             : ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      57             : ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      58             : ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      59             : ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      60             : ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      61             : ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      62             : 
      63             : ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      64             : ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      65             : ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      66             : ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      67             : ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      68             : ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
      69             : 
      70             : ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC);
      71             : ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC);
      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             : END_EXTERN_C()
      91             : 
      92             : #if ZEND_DVAL_TO_LVAL_CAST_OK
      93             : static zend_always_inline zend_long zend_dval_to_lval(double d)
      94             : {
      95             :     if (EXPECTED(zend_finite(d)) && EXPECTED(!zend_isnan(d))) {
      96             :         return (zend_long)d;
      97             :     } else {
      98             :         return 0;
      99             :     }
     100             : }
     101             : #elif SIZEOF_ZEND_LONG == 4
     102             : static zend_always_inline zend_long zend_dval_to_lval(double d)
     103             : {
     104             :         if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
     105             :                 return 0;
     106             :         } else if (d > ZEND_LONG_MAX || d < ZEND_LONG_MIN) {
     107             :                 double  two_pow_32 = pow(2., 32.),
     108             :                                 dmod;
     109             : 
     110             :                 dmod = fmod(d, two_pow_32);
     111             :                 if (dmod < 0) {
     112             :                         /* we're going to make this number positive; call ceil()
     113             :                          * to simulate rounding towards 0 of the negative number */
     114             :                         dmod = ceil(dmod) + two_pow_32;
     115             :                 }
     116             :                 return (zend_long)(zend_ulong)dmod;
     117             :         }
     118             :         return (zend_long)d;
     119             : }
     120             : #else
     121             : static zend_always_inline zend_long zend_dval_to_lval(double d)
     122             : {
     123       26773 :         if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) {
     124           4 :                 return 0;
     125             :         /* >= as (double)ZEND_LONG_MAX is outside signed range */
     126       26769 :         } else if (d >= ZEND_LONG_MAX || d < ZEND_LONG_MIN) {
     127         157 :                 double  two_pow_64 = pow(2., 64.),
     128             :                                 dmod;
     129             : 
     130         157 :                 dmod = fmod(d, two_pow_64);
     131         157 :                 if (dmod < 0) {
     132             :                         /* no need to call ceil; original double must have had no
     133             :                          * fractional part, hence dmod does not have one either */
     134           7 :                         dmod += two_pow_64;
     135             :                 }
     136         157 :                 return (zend_long)(zend_ulong)dmod;
     137             :         }
     138       26612 :         return (zend_long)d;
     139             : }
     140             : #endif
     141             : /* }}} */
     142             : 
     143             : #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
     144             : #define ZEND_IS_XDIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
     145             : 
     146             : 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)
     147             : {
     148     1098446 :         if (*str > '9') {
     149      135375 :                 return 0;
     150             :         }
     151      963071 :         return _is_numeric_string_ex(str, length, lval, dval, allow_errors, oflow_info);
     152             : }
     153             : 
     154             : static zend_always_inline zend_uchar is_numeric_string(const char *str, size_t length, zend_long *lval, double *dval, int allow_errors) {
     155      157992 :     return is_numeric_string_ex(str, length, lval, dval, allow_errors, NULL);
     156             : }
     157             : 
     158             : ZEND_API zend_uchar is_numeric_str_function(const zend_string *str, zend_long *lval, double *dval);
     159             : 
     160             : static zend_always_inline const char *
     161             : zend_memnstr(const char *haystack, const char *needle, size_t needle_len, char *end)
     162             : {
     163     2667635 :         const char *p = haystack;
     164     2667635 :         const char ne = needle[needle_len-1];
     165             :         ptrdiff_t off_p;
     166             :         size_t off_s;
     167             : 
     168     2667635 :         if (needle_len == 1) {
     169     1856803 :                 return (char *)memchr(p, *needle, (end-p));
     170             :         }
     171             : 
     172      810832 :         off_p = end - haystack;
     173      810832 :         off_s = (off_p > 0) ? (size_t)off_p : 0;
     174      810832 :         if (needle_len > off_s) {
     175        6434 :                 return NULL;
     176             :         }
     177             : 
     178      804398 :         end -= needle_len;
     179             : 
     180     4108350 :         while (p <= end) {
     181     4038324 :                 if ((p = (char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
     182      543424 :                         if (!memcmp(needle, p, needle_len-1)) {
     183      181954 :                                 return p;
     184             :                         }
     185             :                 }
     186             : 
     187     3856370 :                 if (p == NULL) {
     188      552418 :                         return NULL;
     189             :                 }
     190             : 
     191     3303952 :                 p++;
     192             :         }
     193             : 
     194       70026 :         return NULL;
     195             : }
     196             : 
     197             : static zend_always_inline const void *zend_memrchr(const void *s, int c, size_t n)
     198             : {
     199             :         register const unsigned char *e;
     200             : 
     201     3268089 :         if (n <= 0) {
     202         428 :                 return NULL;
     203             :         }
     204             : 
     205    47578051 :         for (e = (const unsigned char *)s + n - 1; e >= (const unsigned char *)s; e--) {
     206    44347425 :                 if (*e == (const unsigned char)c) {
     207       37035 :                         return (const void *)e;
     208             :                 }
     209             :         }
     210             : 
     211     3230626 :         return NULL;
     212             : }
     213             : 
     214             : BEGIN_EXTERN_C()
     215             : ZEND_API int increment_function(zval *op1);
     216             : ZEND_API int decrement_function(zval *op2);
     217             : 
     218             : ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC);
     219             : ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC);
     220             : ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
     221             : ZEND_API void convert_to_long(zval *op);
     222             : ZEND_API void convert_to_double(zval *op);
     223             : ZEND_API void convert_to_long_base(zval *op, int base);
     224             : ZEND_API void convert_to_null(zval *op);
     225             : ZEND_API void convert_to_boolean(zval *op);
     226             : ZEND_API void convert_to_array(zval *op);
     227             : ZEND_API void convert_to_object(zval *op);
     228             : ZEND_API void multi_convert_to_long_ex(int argc, ...);
     229             : ZEND_API void multi_convert_to_double_ex(int argc, ...);
     230             : ZEND_API void multi_convert_to_string_ex(int argc, ...);
     231             : 
     232             : ZEND_API zend_long _zval_get_long_func(zval *op TSRMLS_DC);
     233             : ZEND_API double _zval_get_double_func(zval *op TSRMLS_DC);
     234             : ZEND_API zend_string *_zval_get_string_func(zval *op TSRMLS_DC);
     235             : 
     236             : static zend_always_inline zend_long _zval_get_long(zval *op TSRMLS_DC) {
     237      394619 :         return Z_TYPE_P(op) == IS_LONG ? Z_LVAL_P(op) : _zval_get_long_func(op TSRMLS_CC);
     238             : }
     239             : static zend_always_inline double _zval_get_double(zval *op TSRMLS_DC) {
     240      206335 :         return Z_TYPE_P(op) == IS_DOUBLE ? Z_DVAL_P(op) : _zval_get_double_func(op TSRMLS_CC);
     241             : }
     242             : static zend_always_inline zend_string *_zval_get_string(zval *op TSRMLS_DC) {
     243     6719965 :         return Z_TYPE_P(op) == IS_STRING ? zend_string_copy(Z_STR_P(op)) : _zval_get_string_func(op TSRMLS_CC);
     244             : }
     245             : 
     246             : #define zval_get_long(op) _zval_get_long((op) TSRMLS_CC)
     247             : #define zval_get_double(op) _zval_get_double((op) TSRMLS_CC)
     248             : #define zval_get_string(op) _zval_get_string((op) TSRMLS_CC)
     249             : 
     250             : ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2);
     251             : ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2);
     252             : #define convert_to_cstring(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_cstring((op) ZEND_FILE_LINE_CC); }
     253             : #define convert_to_string(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
     254             : 
     255             : ZEND_API int zval_is_true(zval *op);
     256             : ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
     257             : ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
     258             : ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC);
     259             : ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
     260             : ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
     261             : #if HAVE_STRCOLL
     262             : ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
     263             : #endif
     264             : 
     265             : ZEND_API void zend_str_tolower(char *str, size_t length);
     266             : ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, size_t length);
     267             : ZEND_API char *zend_str_tolower_dup(const char *source, size_t length);
     268             : 
     269             : ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
     270             : ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
     271             : ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
     272             : ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3);
     273             : ZEND_API int zend_binary_strcmp(const char *s1, size_t len1, const char *s2, size_t len2);
     274             : ZEND_API int zend_binary_strncmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     275             : ZEND_API int zend_binary_strcasecmp(const char *s1, size_t len1, const char *s2, size_t len2);
     276             : ZEND_API int zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     277             : ZEND_API int zend_binary_strcasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2);
     278             : ZEND_API int zend_binary_strncasecmp_l(const char *s1, size_t len1, const char *s2, size_t len2, size_t length);
     279             : 
     280             : ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2);
     281             : ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC);
     282             : ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC);
     283             : ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC);
     284             : 
     285             : ZEND_API int zend_atoi(const char *str, int str_len);
     286             : ZEND_API zend_long zend_atol(const char *str, int str_len);
     287             : 
     288             : ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
     289             : 
     290             : #define convert_to_ex_master(pzv, lower_type, upper_type)       \
     291             :         if (Z_TYPE_P(pzv)!=upper_type) {                                        \
     292             :                 SEPARATE_ZVAL_IF_NOT_REF(pzv);                                          \
     293             :                 convert_to_##lower_type(pzv);                                           \
     294             :         }
     295             : 
     296             : #define convert_to_explicit_type(pzv, type)             \
     297             :         do {                                                                            \
     298             :                 switch (type) {                                                 \
     299             :                         case IS_NULL:                                           \
     300             :                                 convert_to_null(pzv);                   \
     301             :                                 break;                                                  \
     302             :                         case IS_LONG:                                           \
     303             :                                 convert_to_long(pzv);                   \
     304             :                                 break;                                                  \
     305             :                         case IS_DOUBLE:                                         \
     306             :                                 convert_to_double(pzv);                 \
     307             :                                 break;                                                  \
     308             :                         case _IS_BOOL:                                          \
     309             :                                 convert_to_boolean(pzv);                \
     310             :                                 break;                                                  \
     311             :                         case IS_ARRAY:                                          \
     312             :                                 convert_to_array(pzv);                  \
     313             :                                 break;                                                  \
     314             :                         case IS_OBJECT:                                         \
     315             :                                 convert_to_object(pzv);                 \
     316             :                                 break;                                                  \
     317             :                         case IS_STRING:                                         \
     318             :                                 convert_to_string(pzv);                 \
     319             :                                 break;                                                  \
     320             :                         default:                                                        \
     321             :                                 assert(0);                                              \
     322             :                                 break;                                                  \
     323             :                 }                                                                               \
     324             :         } while (0);
     325             : 
     326             : #define convert_to_explicit_type_ex(pzv, str_type)      \
     327             :         if (Z_TYPE_P(pzv) != str_type) {                                \
     328             :                 SEPARATE_ZVAL_IF_NOT_REF(pzv);                          \
     329             :                 convert_to_explicit_type(pzv, str_type);        \
     330             :         }
     331             : 
     332             : #define convert_to_boolean_ex(pzv)      convert_to_ex_master(pzv, boolean, _IS_BOOL)
     333             : #define convert_to_long_ex(pzv)         convert_to_ex_master(pzv, long, IS_LONG)
     334             : #define convert_to_double_ex(pzv)       convert_to_ex_master(pzv, double, IS_DOUBLE)
     335             : #define convert_to_string_ex(pzv)       convert_to_ex_master(pzv, string, IS_STRING)
     336             : #define convert_to_array_ex(pzv)        convert_to_ex_master(pzv, array, IS_ARRAY)
     337             : #define convert_to_object_ex(pzv)       convert_to_ex_master(pzv, object, IS_OBJECT)
     338             : #define convert_to_null_ex(pzv)         convert_to_ex_master(pzv, null, IS_NULL)
     339             : 
     340             : #define convert_scalar_to_number_ex(pzv)                                                        \
     341             :         if (Z_TYPE_P(pzv)!=IS_LONG && Z_TYPE_P(pzv)!=IS_DOUBLE) {               \
     342             :                 SEPARATE_ZVAL_IF_NOT_REF(pzv);                                                          \
     343             :                 convert_scalar_to_number(pzv TSRMLS_CC);                                        \
     344             :         }
     345             : 
     346             : #if HAVE_SETLOCALE && defined(ZEND_WIN32) && !defined(ZTS) && defined(_MSC_VER) && (_MSC_VER >= 1400)
     347             : /* This is performance improvement of tolower() on Windows and VC2005
     348             :  * Gives 10-18% on bench.php
     349             :  */
     350             : #define ZEND_USE_TOLOWER_L 1
     351             : #endif
     352             : 
     353             : #ifdef ZEND_USE_TOLOWER_L
     354             : ZEND_API void zend_update_current_locale(void);
     355             : #else
     356             : #define zend_update_current_locale()
     357             : #endif
     358             : 
     359             : /* The offset in bytes between the value and type fields of a zval */
     360             : #define ZVAL_OFFSETOF_TYPE      \
     361             :         (offsetof(zval, u1.type_info) - offsetof(zval, value))
     362             : 
     363             : static zend_always_inline int fast_increment_function(zval *op1)
     364             : {
     365     5288205 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     366             : #if defined(__GNUC__) && defined(__i386__)
     367             :                 __asm__(
     368             :                         "incl (%0)\n\t"
     369             :                         "jno  0f\n\t"
     370             :                         "movl $0x0, (%0)\n\t"
     371             :                         "movl $0x41e00000, 0x4(%0)\n\t"
     372             :                         "movl %1, %c2(%0)\n"
     373             :                         "0:"
     374             :                         :
     375             :                         : "r"(&op1->value),
     376             :                           "n"(IS_DOUBLE),
     377             :                           "n"(ZVAL_OFFSETOF_TYPE)
     378             :                         : "cc");
     379             : #elif defined(__GNUC__) && defined(__x86_64__)
     380     5288205 :                 __asm__(
     381             :                         "incq (%0)\n\t"
     382             :                         "jno  0f\n\t"
     383             :                         "movl $0x0, (%0)\n\t"
     384             :                         "movl $0x43e00000, 0x4(%0)\n\t"
     385             :                         "movl %1, %c2(%0)\n"
     386             :                         "0:"
     387             :                         :
     388     5288205 :                         : "r"(&op1->value),
     389             :                           "n"(IS_DOUBLE),
     390             :                           "n"(ZVAL_OFFSETOF_TYPE)
     391             :                         : "cc");
     392             : #else
     393             :                 if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
     394             :                         /* switch to double */
     395             :                         ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
     396             :                 } else {
     397             :                         Z_LVAL_P(op1)++;
     398             :                 }
     399             : #endif
     400     5288205 :                 return SUCCESS;
     401             :         }
     402           0 :         return increment_function(op1);
     403             : }
     404             : 
     405             : static zend_always_inline int fast_decrement_function(zval *op1)
     406             : {
     407      433843 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     408             : #if defined(__GNUC__) && defined(__i386__)
     409             :                 __asm__(
     410             :                         "decl (%0)\n\t"
     411             :                         "jno  0f\n\t"
     412             :                         "movl $0x00200000, (%0)\n\t"
     413             :                         "movl $0xc1e00000, 0x4(%0)\n\t"
     414             :                         "movl %1,%c2(%0)\n"
     415             :                         "0:"
     416             :                         :
     417             :                         : "r"(&op1->value),
     418             :                           "n"(IS_DOUBLE),
     419             :                           "n"(ZVAL_OFFSETOF_TYPE)
     420             :                         : "cc");
     421             : #elif defined(__GNUC__) && defined(__x86_64__)
     422      433843 :                 __asm__(
     423             :                         "decq (%0)\n\t"
     424             :                         "jno  0f\n\t"
     425             :                         "movl $0x00000000, (%0)\n\t"
     426             :                         "movl $0xc3e00000, 0x4(%0)\n\t"
     427             :                         "movl %1,%c2(%0)\n"
     428             :                         "0:"
     429             :                         :
     430      433843 :                         : "r"(&op1->value),
     431             :                           "n"(IS_DOUBLE),
     432             :                           "n"(ZVAL_OFFSETOF_TYPE)
     433             :                         : "cc");
     434             : #else
     435             :                 if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
     436             :                         /* switch to double */
     437             :                         ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
     438             :                 } else {
     439             :                         Z_LVAL_P(op1)--;
     440             :                 }
     441             : #endif
     442      433843 :                 return SUCCESS;
     443             :         }
     444           0 :         return decrement_function(op1);
     445             : }
     446             : 
     447             : static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     448             : {
     449      747640 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     450      745909 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     451             : #if defined(__GNUC__) && defined(__i386__)
     452             :                 __asm__(
     453             :                         "movl      (%1), %%eax\n\t"
     454             :                         "addl   (%2), %%eax\n\t"
     455             :                         "jo     0f\n\t"     
     456             :                         "movl   %%eax, (%0)\n\t"
     457             :                         "movl   %3, %c5(%0)\n\t"
     458             :                         "jmp    1f\n"
     459             :                         "0:\n\t"
     460             :                         "fildl     (%1)\n\t"
     461             :                         "fildl     (%2)\n\t"
     462             :                         "faddp     %%st, %%st(1)\n\t"
     463             :                         "movl   %4, %c5(%0)\n\t"
     464             :                         "fstpl     (%0)\n"
     465             :                         "1:"
     466             :                         : 
     467             :                         : "r"(&result->value),
     468             :                           "r"(&op1->value),
     469             :                           "r"(&op2->value),
     470             :                           "n"(IS_LONG),
     471             :                           "n"(IS_DOUBLE),
     472             :                           "n"(ZVAL_OFFSETOF_TYPE)
     473             :                         : "eax","cc");
     474             : #elif defined(__GNUC__) && defined(__x86_64__)
     475      745813 :                 __asm__(
     476             :                         "movq      (%1), %%rax\n\t"
     477             :                         "addq   (%2), %%rax\n\t"
     478             :                         "jo     0f\n\t"     
     479             :                         "movq   %%rax, (%0)\n\t"
     480             :                         "movl   %3, %c5(%0)\n\t"
     481             :                         "jmp    1f\n"
     482             :                         "0:\n\t"
     483             :                         "fildq     (%1)\n\t"
     484             :                         "fildq     (%2)\n\t"
     485             :                         "faddp     %%st, %%st(1)\n\t"
     486             :                         "movl   %4, %c5(%0)\n\t"
     487             :                         "fstpl     (%0)\n"
     488             :                         "1:"
     489             :                         : 
     490      745813 :                         : "r"(&result->value),
     491      745813 :                           "r"(&op1->value),
     492      745813 :                           "r"(&op2->value),
     493             :                           "n"(IS_LONG),
     494             :                           "n"(IS_DOUBLE),
     495             :                           "n"(ZVAL_OFFSETOF_TYPE)
     496             :                         : "rax","cc");
     497             : #else
     498             :                         /*
     499             :                          * 'result' may alias with op1 or op2, so we need to
     500             :                          * ensure that 'result' is not updated until after we
     501             :                          * have read the values of op1 and op2.
     502             :                          */
     503             : 
     504             :                         if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     505             :                                 && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
     506             :                                 ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
     507             :                         } else {
     508             :                                 ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
     509             :                         }
     510             : #endif
     511      745813 :                         return SUCCESS;
     512          96 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     513          78 :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
     514          78 :                         return SUCCESS;
     515             :                 }
     516        1731 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     517        1306 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     518         202 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
     519         202 :                         return SUCCESS;
     520        1104 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     521        1095 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
     522        1095 :                         return SUCCESS;
     523             :                 }
     524             :         }
     525         452 :         return add_function(result, op1, op2 TSRMLS_CC);
     526             : }
     527             : 
     528             : static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     529             : {
     530      342786 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     531      229939 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     532             : #if defined(__GNUC__) && defined(__i386__)
     533             :                 __asm__(
     534             :                         "movl      (%1), %%eax\n\t"
     535             :                         "subl   (%2), %%eax\n\t"
     536             :                         "jo     0f\n\t"     
     537             :                         "movl   %%eax, (%0)\n\t"
     538             :                         "movl   %3, %c5(%0)\n\t"
     539             :                         "jmp    1f\n"
     540             :                         "0:\n\t"
     541             :                         "fildl     (%2)\n\t"
     542             :                         "fildl     (%1)\n\t"
     543             : #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
     544             :                         "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
     545             : #else
     546             :                         "fsubp     %%st, %%st(1)\n\t"
     547             : #endif
     548             :                         "movl   %4, %c5(%0)\n\t"
     549             :                         "fstpl     (%0)\n"
     550             :                         "1:"
     551             :                         : 
     552             :                         : "r"(&result->value),
     553             :                           "r"(&op1->value),
     554             :                           "r"(&op2->value),
     555             :                           "n"(IS_LONG),
     556             :                           "n"(IS_DOUBLE),
     557             :                           "n"(ZVAL_OFFSETOF_TYPE)
     558             :                         : "eax","cc");
     559             : #elif defined(__GNUC__) && defined(__x86_64__)
     560      229860 :                 __asm__(
     561             :                         "movq      (%1), %%rax\n\t"
     562             :                         "subq   (%2), %%rax\n\t"
     563             :                         "jo     0f\n\t"     
     564             :                         "movq   %%rax, (%0)\n\t"
     565             :                         "movl   %3, %c5(%0)\n\t"
     566             :                         "jmp    1f\n"
     567             :                         "0:\n\t"
     568             :                         "fildq     (%2)\n\t"
     569             :                         "fildq     (%1)\n\t"
     570             : #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
     571             :                         "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
     572             : #else
     573             :                         "fsubp     %%st, %%st(1)\n\t"
     574             : #endif
     575             :                         "movl   %4, %c5(%0)\n\t"
     576             :                         "fstpl     (%0)\n"
     577             :                         "1:"
     578             :                         : 
     579      229860 :                         : "r"(&result->value),
     580      229860 :                           "r"(&op1->value),
     581      229860 :                           "r"(&op2->value),
     582             :                           "n"(IS_LONG),
     583             :                           "n"(IS_DOUBLE),
     584             :                           "n"(ZVAL_OFFSETOF_TYPE)
     585             :                         : "rax","cc");
     586             : #else
     587             :                         ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
     588             : 
     589             :                         if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
     590             :                                 && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
     591             :                                 ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
     592             :                         }
     593             : #endif
     594      229860 :                         return SUCCESS;
     595          79 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     596          62 :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
     597          62 :                         return SUCCESS;
     598             :                 }
     599      112847 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     600      112627 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     601      112608 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
     602      112608 :                         return SUCCESS;
     603          19 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     604          19 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
     605          19 :                         return SUCCESS;
     606             :                 }
     607             :         }
     608         237 :         return sub_function(result, op1, op2 TSRMLS_CC);
     609             : }
     610             : 
     611             : static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     612             : {
     613      444872 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     614      444406 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     615             :                         zend_long overflow;
     616             : 
     617      443789 :                         ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
     618      443789 :                         Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
     619      443789 :                         return SUCCESS;
     620         617 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     621         614 :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
     622         614 :                         return SUCCESS;
     623             :                 }
     624         466 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     625         239 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     626         170 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
     627         170 :                         return SUCCESS;
     628          69 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     629          69 :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
     630          69 :                         return SUCCESS;
     631             :                 }
     632             :         }
     633         230 :         return mul_function(result, op1, op2 TSRMLS_CC);
     634             : }
     635             : 
     636             : static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     637             : {
     638             : #if 0
     639             :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && 0) {
     640             :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     641             :                         if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
     642             :                                 zend_error(E_WARNING, "Division by zero");
     643             :                                 ZVAL_BOOL(result, 0);
     644             :                                 return FAILURE;
     645             :                         } else if (UNEXPECTED(Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
     646             :                                 /* Prevent overflow error/crash */
     647             :                                 ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
     648             :                         } else if (EXPECTED(Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0)) {
     649             :                                 /* integer */
     650             :                                 ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
     651             :                         } else {
     652             :                                 ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / ((double)Z_LVAL_P(op2)));
     653             :                         }
     654             :                         return SUCCESS;
     655             :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     656             :                         if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
     657             :                                 zend_error(E_WARNING, "Division by zero");
     658             :                                 ZVAL_BOOL(result, 0);
     659             :                                 return FAILURE;
     660             :                         }
     661             :                         ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) / Z_DVAL_P(op2));
     662             :                         return SUCCESS;
     663             :                 }
     664             :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE) && 0) {
     665             :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     666             :                         if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
     667             :                                 zend_error(E_WARNING, "Division by zero");
     668             :                                 ZVAL_BOOL(result, 0);
     669             :                                 return FAILURE;
     670             :                         }
     671             :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
     672             :                         return SUCCESS;
     673             :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     674             :                         if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
     675             :                                 zend_error(E_WARNING, "Division by zero");
     676             :                                 ZVAL_BOOL(result, 0);
     677             :                                 return FAILURE;
     678             :                         }
     679             :                         ZVAL_DOUBLE(result, Z_DVAL_P(op1) / ((double)Z_LVAL_P(op2)));
     680             :                         return SUCCESS;
     681             :                 }
     682             :         }
     683             : #endif
     684      147041 :         return div_function(result, op1, op2 TSRMLS_CC);
     685             : }
     686             : 
     687             : static zend_always_inline int fast_mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     688             : {
     689       69186 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     690       68865 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     691       68846 :                         if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
     692          13 :                                 zend_error(E_WARNING, "Division by zero");
     693          13 :                                 ZVAL_BOOL(result, 0);
     694          13 :                                 return FAILURE;
     695       68833 :                         } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
     696             :                                 /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
     697          13 :                                 ZVAL_LONG(result, 0);
     698          13 :                                 return SUCCESS;
     699             :                         }
     700       68820 :                         ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
     701       68820 :                         return SUCCESS;
     702             :                 }
     703             :         }
     704         340 :         return mod_function(result, op1, op2 TSRMLS_CC);
     705             : }
     706             : 
     707             : static zend_always_inline int fast_equal_check_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     708             : {
     709      504996 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     710        8066 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     711        7865 :                         return Z_LVAL_P(op1) == Z_LVAL_P(op2);
     712         201 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     713           8 :                         return ((double)Z_LVAL_P(op1)) == Z_DVAL_P(op2);
     714             :                 }
     715      496930 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     716         316 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     717          16 :                         return Z_DVAL_P(op1) == Z_DVAL_P(op2);
     718         300 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     719         128 :                         return Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2));
     720             :                 }
     721      496614 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
     722      482791 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
     723      482140 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
     724          46 :                                 return 1;
     725      482094 :                         } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
     726      478272 :                                 if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
     727      435321 :                                         return 0;
     728             :                                 } else {
     729       42951 :                                         return memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0;
     730             :                                 }
     731             :                         } else {
     732        3822 :                                 zendi_smart_strcmp(result, op1, op2);
     733        3822 :                                 return Z_LVAL_P(result) == 0;
     734             :                         }
     735             :                 }
     736             :         }
     737       14839 :         compare_function(result, op1, op2 TSRMLS_CC);
     738       14839 :         return Z_LVAL_P(result) == 0;
     739             : }
     740             : 
     741             : static zend_always_inline void fast_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     742             : {
     743     2511940 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     744     1335335 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     745     1333963 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) == Z_LVAL_P(op2));
     746             :                         return;
     747        1372 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     748          19 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
     749             :                         return;
     750             :                 }
     751     1176605 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     752          90 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     753          41 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) == Z_DVAL_P(op2));
     754             :                         return;
     755          49 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     756          14 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
     757             :                         return;
     758             :                 }
     759     1176515 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
     760     1081443 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
     761     1081337 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
     762        1083 :                                 ZVAL_TRUE(result);
     763             :                                 return;
     764     1080254 :                         } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
     765      940135 :                                 if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
     766      428171 :                                         ZVAL_FALSE(result);
     767             :                                         return;
     768             :                                 } else {
     769      511964 :                                         ZVAL_BOOL(result, memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
     770             :                                         return;
     771             :                                 }
     772             :                         } else {
     773      140119 :                                 zendi_smart_strcmp(result, op1, op2);
     774      140119 :                                 ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
     775             :                                 return;
     776             :                         }
     777             :                 }
     778             :         }
     779       96566 :         compare_function(result, op1, op2 TSRMLS_CC);
     780       96565 :         ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
     781             : }
     782             : 
     783             : static zend_always_inline void fast_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     784             : {
     785      484691 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     786      108504 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     787      106859 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) != Z_LVAL_P(op2));
     788             :                         return;
     789        1645 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     790          20 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
     791             :                         return;
     792             :                 }
     793      376187 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     794         116 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     795          13 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) != Z_DVAL_P(op2));
     796             :                         return;
     797         103 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     798           0 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
     799             :                         return;
     800             :                 }
     801      376071 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
     802      182539 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
     803      179150 :                         if (Z_STR_P(op1) == Z_STR_P(op2)) {
     804         105 :                                 ZVAL_FALSE(result);
     805             :                                 return;
     806      179045 :                         } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
     807       33403 :                                 if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
     808       13701 :                                         ZVAL_TRUE(result);
     809             :                                         return;
     810             :                                 } else {
     811       19702 :                                         ZVAL_BOOL(result, memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
     812             :                                         return;
     813             :                                 }
     814             :                         } else {
     815      145642 :                                 zendi_smart_strcmp(result, op1, op2);
     816      145642 :                                 ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
     817             :                                 return;
     818             :                         }
     819             :                 }
     820             :         }
     821      198649 :         compare_function(result, op1, op2 TSRMLS_CC);
     822      198649 :         ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
     823             : }
     824             : 
     825             : static zend_always_inline void fast_is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     826             : {
     827     7946405 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     828     7489452 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     829     7186598 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) < Z_LVAL_P(op2));
     830             :                         return;
     831      302854 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     832      213547 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
     833             :                         return;
     834             :                 }
     835      456953 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     836      112780 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     837         188 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) < Z_DVAL_P(op2));
     838             :                         return;
     839      112592 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     840      112558 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
     841             :                         return;
     842             :                 }
     843             :         }
     844      433514 :         compare_function(result, op1, op2 TSRMLS_CC);
     845      433514 :         ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
     846             : }
     847             : 
     848             : static zend_always_inline void fast_is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     849             : {
     850      578457 :         if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
     851      477827 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     852      461755 :                         ZVAL_BOOL(result, Z_LVAL_P(op1) <= Z_LVAL_P(op2));
     853             :                         return;
     854       16072 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     855       15964 :                         ZVAL_BOOL(result, (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
     856             :                         return;
     857             :                 }
     858      100630 :         } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
     859          86 :                 if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
     860          19 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) <= Z_DVAL_P(op2));
     861             :                         return;
     862          67 :                 } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
     863          25 :                         ZVAL_BOOL(result, Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
     864             :                         return;
     865             :                 }
     866             :         }
     867      100694 :         compare_function(result, op1, op2 TSRMLS_CC);
     868      100694 :         ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
     869             : }
     870             : 
     871             : static zend_always_inline void fast_is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     872             : {
     873     3467378 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
     874     2450138 :                 ZVAL_BOOL(result, 0);
     875             :                 return;
     876             :         }
     877     1017240 :         is_identical_function(result, op1, op2 TSRMLS_CC);
     878             : }
     879             : 
     880             : static zend_always_inline void fast_is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
     881             : {
     882      537397 :         if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
     883      480392 :                 ZVAL_BOOL(result, 1);
     884             :                 return;
     885             :         }
     886       57005 :         is_identical_function(result, op1, op2 TSRMLS_CC);
     887       57005 :         ZVAL_BOOL(result, Z_TYPE_P(result) != IS_TRUE);
     888             : }
     889             : 
     890             : #define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op)                                            \
     891             :         if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                             \
     892             :                 && op1 == result                                                                                   \
     893             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, get))                                                           \
     894             :                 && EXPECTED(Z_OBJ_HANDLER_P(op1, set))) {                                                          \
     895             :                 int ret;                                                                                           \
     896             :                 zval rv;                                                                                           \
     897             :                 zval *objval = Z_OBJ_HANDLER_P(op1, get)(op1, &rv TSRMLS_CC);                                      \
     898             :                 Z_ADDREF_P(objval);                                                                                \
     899             :                 ret = binary_op(objval, objval, op2 TSRMLS_CC);                                                    \
     900             :                 Z_OBJ_HANDLER_P(op1, set)(op1, objval TSRMLS_CC);                                                  \
     901             :                 zval_ptr_dtor(objval);                                                                             \
     902             :                 return ret;                                                                                        \
     903             :         } else if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                      \
     904             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))) {                                               \
     905             :                 if (EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2 TSRMLS_CC))) { \
     906             :                         return SUCCESS;                                                                                \
     907             :                 }                                                                                                  \
     908             :         }
     909             : 
     910             : #define ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)                                                       \
     911             :         if (UNEXPECTED(Z_TYPE_P(op2) == IS_OBJECT)                                                             \
     912             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op2, do_operation))                                                  \
     913             :                 && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2 TSRMLS_CC))) {  \
     914             :                 return SUCCESS;                                                                                    \
     915             :         }
     916             : 
     917             : #define ZEND_TRY_BINARY_OBJECT_OPERATION(opcode, binary_op)                                                \
     918             :         ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode, binary_op)                                                \
     919             :         else                                                                                                   \
     920             :         ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)
     921             : 
     922             : #define ZEND_TRY_UNARY_OBJECT_OPERATION(opcode)                                                            \
     923             :         if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT)                                                             \
     924             :                 && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))                                                  \
     925             :                 && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL TSRMLS_CC))) { \
     926             :                 return SUCCESS;                                                                                    \
     927             :         }
     928             : 
     929             : /* buf points to the END of the buffer */
     930             : static zend_always_inline char *zend_print_ulong_to_buf(char *buf, zend_ulong num) {
     931     1391487 :         *buf = '\0';
     932             :         do {
     933     2443649 :                 *--buf = (char) (num % 10) + '0';
     934     2443649 :                 num /= 10;
     935     2443649 :         } while (num > 0);
     936     1391487 :         return buf;
     937             : }
     938             : 
     939             : /* buf points to the END of the buffer */
     940             : static zend_always_inline char *zend_print_long_to_buf(char *buf, zend_long num) {
     941     1009457 :         if (num < 0) {
     942       12178 :             char *result = zend_print_ulong_to_buf(buf, ~((zend_ulong) num) + 1);
     943        6089 :             *--result = '-';
     944        6089 :                 return result;
     945             :         } else {
     946     2006736 :             return zend_print_ulong_to_buf(buf, num);
     947             :         }
     948             : }
     949             : 
     950             : ZEND_API zend_string *zend_long_to_str(zend_long num);
     951             : 
     952             : END_EXTERN_C()
     953             : 
     954             : #endif
     955             : 
     956             : /*
     957             :  * Local variables:
     958             :  * tab-width: 4
     959             :  * c-basic-offset: 4
     960             :  * indent-tabs-mode: t
     961             :  * End:
     962             :  */

Generated by: LCOV version 1.10

Generated at Sat, 22 Nov 2014 23:01:12 +0000 (3 days ago)

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