Annotation of embedaddon/php/Zend/zend_operators.h, revision 1.1.1.2

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | Zend Engine                                                          |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1998-2012 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: 
1.1.1.2 ! misho      20: /* $Id$ */
1.1       misho      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 HAVE_IEEEFP_H
                     30: #include <ieeefp.h>
                     31: #endif
                     32: 
                     33: #include "zend_strtod.h"
1.1.1.2 ! misho      34: #include "zend_multiply.h"
1.1       misho      35: 
                     36: #if 0&&HAVE_BCMATH
                     37: #include "ext/bcmath/libbcmath/src/bcmath.h"
                     38: #endif
                     39: 
1.1.1.2 ! misho      40: #define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
        !            41: 
1.1       misho      42: BEGIN_EXTERN_C()
                     43: ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     44: ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     45: ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     46: ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     47: ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     48: ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     49: ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC);
                     50: ZEND_API int bitwise_not_function(zval *result, zval *op1 TSRMLS_DC);
                     51: ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     52: ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     53: ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     54: ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     55: ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     56: ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     57: 
                     58: ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     59: ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     60: ZEND_API int is_not_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     61: ZEND_API int is_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     62: ZEND_API int is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     63: ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                     64: 
                     65: ZEND_API zend_bool instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC);
                     66: ZEND_API zend_bool instanceof_function(const zend_class_entry *instance_ce, const zend_class_entry *ce TSRMLS_DC);
                     67: END_EXTERN_C()
                     68: 
                     69: #if ZEND_DVAL_TO_LVAL_CAST_OK
                     70: # define zend_dval_to_lval(d) ((long) (d))
                     71: #elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
                     72: static zend_always_inline long zend_dval_to_lval(double d)
                     73: {
                     74:        if (d > LONG_MAX || d < LONG_MIN) {
                     75:                return (long)(unsigned long)(zend_long64) d;
                     76:        }
                     77:        return (long) d;
                     78: }
                     79: #else
                     80: static zend_always_inline long zend_dval_to_lval(double d)
                     81: {
                     82:        if (d > LONG_MAX) {
                     83:                return (long)(unsigned long) d;
                     84:        }
                     85:        return (long) d;
                     86: }
                     87: #endif
                     88: /* }}} */
                     89: 
                     90: #define ZEND_IS_DIGIT(c) ((c) >= '0' && (c) <= '9')
                     91: #define ZEND_IS_XDIGIT(c) (((c) >= 'A' && (c) <= 'F') || ((c) >= 'a' && (c) <= 'f'))
                     92: 
                     93: /**
                     94:  * Checks whether the string "str" with length "length" is numeric. The value
                     95:  * of allow_errors determines whether it's required to be entirely numeric, or
                     96:  * just its prefix. Leading whitespace is allowed.
                     97:  *
                     98:  * The function returns 0 if the string did not contain a valid number; IS_LONG
                     99:  * if it contained a number that fits within the range of a long; or IS_DOUBLE
                    100:  * if the number was out of long range or contained a decimal point/exponent.
                    101:  * The number's value is returned into the respective pointer, *lval or *dval,
                    102:  * if that pointer is not NULL.
                    103:  */
                    104: 
                    105: static inline zend_uchar is_numeric_string(const char *str, int length, long *lval, double *dval, int allow_errors)
                    106: {
                    107:        const char *ptr;
                    108:        int base = 10, digits = 0, dp_or_e = 0;
                    109:        double local_dval;
                    110:        zend_uchar type;
                    111: 
                    112:        if (!length) {
                    113:                return 0;
                    114:        }
                    115: 
                    116:        /* Skip any whitespace
                    117:         * This is much faster than the isspace() function */
                    118:        while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
                    119:                str++;
                    120:                length--;
                    121:        }
                    122:        ptr = str;
                    123: 
                    124:        if (*ptr == '-' || *ptr == '+') {
                    125:                ptr++;
                    126:        }
                    127: 
                    128:        if (ZEND_IS_DIGIT(*ptr)) {
                    129:                /* Handle hex numbers
                    130:                 * str is used instead of ptr to disallow signs and keep old behavior */
                    131:                if (length > 2 && *str == '0' && (str[1] == 'x' || str[1] == 'X')) {
                    132:                        base = 16;
                    133:                        ptr += 2;
                    134:                }
                    135: 
                    136:                /* Skip any leading 0s */
                    137:                while (*ptr == '0') {
                    138:                        ptr++;
                    139:                }
                    140: 
                    141:                /* Count the number of digits. If a decimal point/exponent is found,
                    142:                 * it's a double. Otherwise, if there's a dval or no need to check for
                    143:                 * a full match, stop when there are too many digits for a long */
                    144:                for (type = IS_LONG; !(digits >= MAX_LENGTH_OF_LONG && (dval || allow_errors == 1)); digits++, ptr++) {
                    145: check_digits:
                    146:                        if (ZEND_IS_DIGIT(*ptr) || (base == 16 && ZEND_IS_XDIGIT(*ptr))) {
                    147:                                continue;
                    148:                        } else if (base == 10) {
                    149:                                if (*ptr == '.' && dp_or_e < 1) {
                    150:                                        goto process_double;
                    151:                                } else if ((*ptr == 'e' || *ptr == 'E') && dp_or_e < 2) {
                    152:                                        const char *e = ptr + 1;
                    153: 
                    154:                                        if (*e == '-' || *e == '+') {
                    155:                                                ptr = e++;
                    156:                                        }
                    157:                                        if (ZEND_IS_DIGIT(*e)) {
                    158:                                                goto process_double;
                    159:                                        }
                    160:                                }
                    161:                        }
                    162: 
                    163:                        break;
                    164:                }
                    165: 
                    166:                if (base == 10) {
                    167:                        if (digits >= MAX_LENGTH_OF_LONG) {
                    168:                                dp_or_e = -1;
                    169:                                goto process_double;
                    170:                        }
                    171:                } else if (!(digits < SIZEOF_LONG * 2 || (digits == SIZEOF_LONG * 2 && ptr[-digits] <= '7'))) {
                    172:                        if (dval) {
1.1.1.2 ! misho     173:                                local_dval = zend_hex_strtod(str, &ptr);
1.1       misho     174:                        }
                    175:                        type = IS_DOUBLE;
                    176:                }
                    177:        } else if (*ptr == '.' && ZEND_IS_DIGIT(ptr[1])) {
                    178: process_double:
                    179:                type = IS_DOUBLE;
                    180: 
                    181:                /* If there's a dval, do the conversion; else continue checking
                    182:                 * the digits if we need to check for a full match */
                    183:                if (dval) {
1.1.1.2 ! misho     184:                        local_dval = zend_strtod(str, &ptr);
1.1       misho     185:                } else if (allow_errors != 1 && dp_or_e != -1) {
                    186:                        dp_or_e = (*ptr++ == '.') ? 1 : 2;
                    187:                        goto check_digits;
                    188:                }
                    189:        } else {
                    190:                return 0;
                    191:        }
                    192: 
                    193:        if (ptr != str + length) {
                    194:                if (!allow_errors) {
                    195:                        return 0;
                    196:                }
                    197:                if (allow_errors == -1) {
                    198:                        zend_error(E_NOTICE, "A non well formed numeric value encountered");
                    199:                }
                    200:        }
                    201: 
                    202:        if (type == IS_LONG) {
                    203:                if (digits == MAX_LENGTH_OF_LONG - 1) {
                    204:                        int cmp = strcmp(&ptr[-digits], long_min_digits);
                    205: 
                    206:                        if (!(cmp < 0 || (cmp == 0 && *str == '-'))) {
                    207:                                if (dval) {
                    208:                                        *dval = zend_strtod(str, NULL);
                    209:                                }
                    210: 
                    211:                                return IS_DOUBLE;
                    212:                        }
                    213:                }
                    214: 
                    215:                if (lval) {
                    216:                        *lval = strtol(str, NULL, base);
                    217:                }
                    218: 
                    219:                return IS_LONG;
                    220:        } else {
                    221:                if (dval) {
                    222:                        *dval = local_dval;
                    223:                }
                    224: 
                    225:                return IS_DOUBLE;
                    226:        }
                    227: }
                    228: 
                    229: static inline char *
                    230: zend_memnstr(char *haystack, char *needle, int needle_len, char *end)
                    231: {
                    232:        char *p = haystack;
                    233:        char ne = needle[needle_len-1];
                    234: 
                    235:        if (needle_len == 1) {
                    236:                return (char *)memchr(p, *needle, (end-p));
                    237:        }
                    238: 
                    239:        if (needle_len > end-haystack) {
                    240:                return NULL;
                    241:        }
                    242: 
                    243:        end -= needle_len;
                    244: 
                    245:        while (p <= end) {
                    246:                if ((p = (char *)memchr(p, *needle, (end-p+1))) && ne == p[needle_len-1]) {
                    247:                        if (!memcmp(needle, p, needle_len-1)) {
                    248:                                return p;
                    249:                        }
                    250:                }
                    251: 
                    252:                if (p == NULL) {
                    253:                        return NULL;
                    254:                }
                    255: 
                    256:                p++;
                    257:        }
                    258: 
                    259:        return NULL;
                    260: }
                    261: 
1.1.1.2 ! misho     262: static inline const void *zend_memrchr(const void *s, int c, size_t n)
1.1       misho     263: {
1.1.1.2 ! misho     264:        register const unsigned char *e;
1.1       misho     265: 
                    266:        if (n <= 0) {
                    267:                return NULL;
                    268:        }
                    269: 
1.1.1.2 ! misho     270:        for (e = (const unsigned char *)s + n - 1; e >= (const unsigned char *)s; e--) {
        !           271:                if (*e == (const unsigned char)c) {
        !           272:                        return (const void *)e;
1.1       misho     273:                }
                    274:        }
                    275: 
                    276:        return NULL;
                    277: }
                    278: 
                    279: BEGIN_EXTERN_C()
                    280: ZEND_API int increment_function(zval *op1);
                    281: ZEND_API int decrement_function(zval *op2);
                    282: 
                    283: ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC);
                    284: ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
                    285: ZEND_API void convert_to_long(zval *op);
                    286: ZEND_API void convert_to_double(zval *op);
                    287: ZEND_API void convert_to_long_base(zval *op, int base);
                    288: ZEND_API void convert_to_null(zval *op);
                    289: ZEND_API void convert_to_boolean(zval *op);
                    290: ZEND_API void convert_to_array(zval *op);
                    291: ZEND_API void convert_to_object(zval *op);
                    292: ZEND_API void multi_convert_to_long_ex(int argc, ...);
                    293: ZEND_API void multi_convert_to_double_ex(int argc, ...);
                    294: ZEND_API void multi_convert_to_string_ex(int argc, ...);
                    295: ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2);
                    296: ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2);
                    297: #define convert_to_string(op) if ((op)->type != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
                    298: 
                    299: ZEND_API double zend_string_to_double(const char *number, zend_uint length);
                    300: 
                    301: ZEND_API int zval_is_true(zval *op);
                    302: ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                    303: ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
1.1.1.2 ! misho     304: ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC);
1.1       misho     305: ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
1.1.1.2 ! misho     306: ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
1.1       misho     307: #if HAVE_STRCOLL
                    308: ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
                    309: #endif
                    310: 
                    311: ZEND_API void zend_str_tolower(char *str, unsigned int length);
                    312: ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned int length);
                    313: ZEND_API char *zend_str_tolower_dup(const char *source, unsigned int length);
                    314: 
                    315: ZEND_API int zend_binary_zval_strcmp(zval *s1, zval *s2);
                    316: ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3);
                    317: ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2);
                    318: ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3);
                    319: ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint len2);
                    320: ZEND_API int zend_binary_strncmp(const char *s1, uint len1, const char *s2, uint len2, uint length);
                    321: ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, uint len2);
                    322: ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length);
                    323: 
                    324: ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2);
                    325: ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC);
                    326: ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC);
                    327: ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC);
                    328: 
                    329: ZEND_API int zend_atoi(const char *str, int str_len);
                    330: ZEND_API long zend_atol(const char *str, int str_len);
                    331: 
                    332: ZEND_API void zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_DC);
                    333: END_EXTERN_C()
                    334: 
                    335: #define convert_to_ex_master(ppzv, lower_type, upper_type)     \
                    336:        if (Z_TYPE_PP(ppzv)!=IS_##upper_type) {                                 \
                    337:                SEPARATE_ZVAL_IF_NOT_REF(ppzv);                                         \
                    338:                convert_to_##lower_type(*ppzv);                                         \
                    339:        }
                    340: 
                    341: #define convert_to_explicit_type(pzv, type)            \
                    342:        do {                                                                            \
                    343:                switch (type) {                                                 \
                    344:                        case IS_NULL:                                           \
                    345:                                convert_to_null(pzv);                   \
                    346:                                break;                                                  \
                    347:                        case IS_LONG:                                           \
                    348:                                convert_to_long(pzv);                   \
                    349:                                break;                                                  \
                    350:                        case IS_DOUBLE:                                         \
                    351:                                convert_to_double(pzv);                 \
                    352:                                break;                                                  \
                    353:                        case IS_BOOL:                                           \
                    354:                                convert_to_boolean(pzv);                \
                    355:                                break;                                                  \
                    356:                        case IS_ARRAY:                                          \
                    357:                                convert_to_array(pzv);                  \
                    358:                                break;                                                  \
                    359:                        case IS_OBJECT:                                         \
                    360:                                convert_to_object(pzv);                 \
                    361:                                break;                                                  \
                    362:                        case IS_STRING:                                         \
                    363:                                convert_to_string(pzv);                 \
                    364:                                break;                                                  \
                    365:                        default:                                                        \
                    366:                                assert(0);                                              \
                    367:                                break;                                                  \
                    368:                }                                                                               \
                    369:        } while (0);
                    370: 
                    371: #define convert_to_explicit_type_ex(ppzv, str_type)    \
                    372:        if (Z_TYPE_PP(ppzv) != str_type) {                              \
                    373:                SEPARATE_ZVAL_IF_NOT_REF(ppzv);                         \
                    374:                convert_to_explicit_type(*ppzv, str_type);      \
                    375:        }
                    376: 
                    377: #define convert_to_boolean_ex(ppzv)    convert_to_ex_master(ppzv, boolean, BOOL)
                    378: #define convert_to_long_ex(ppzv)       convert_to_ex_master(ppzv, long, LONG)
                    379: #define convert_to_double_ex(ppzv)     convert_to_ex_master(ppzv, double, DOUBLE)
                    380: #define convert_to_string_ex(ppzv)     convert_to_ex_master(ppzv, string, STRING)
                    381: #define convert_to_array_ex(ppzv)      convert_to_ex_master(ppzv, array, ARRAY)
                    382: #define convert_to_object_ex(ppzv)     convert_to_ex_master(ppzv, object, OBJECT)
                    383: #define convert_to_null_ex(ppzv)       convert_to_ex_master(ppzv, null, NULL)
                    384: 
                    385: #define convert_scalar_to_number_ex(ppzv)                                                      \
                    386:        if (Z_TYPE_PP(ppzv)!=IS_LONG && Z_TYPE_PP(ppzv)!=IS_DOUBLE) {   \
                    387:                if (!Z_ISREF_PP(ppzv)) {                                                                        \
                    388:                        SEPARATE_ZVAL(ppzv);                                                                    \
                    389:                }                                                                                                                       \
                    390:                convert_scalar_to_number(*ppzv TSRMLS_CC);                                      \
                    391:        }
                    392: 
                    393: 
                    394: #define Z_LVAL(zval)                   (zval).value.lval
                    395: #define Z_BVAL(zval)                   ((zend_bool)(zval).value.lval)
                    396: #define Z_DVAL(zval)                   (zval).value.dval
                    397: #define Z_STRVAL(zval)                 (zval).value.str.val
                    398: #define Z_STRLEN(zval)                 (zval).value.str.len
                    399: #define Z_ARRVAL(zval)                 (zval).value.ht
                    400: #define Z_OBJVAL(zval)                 (zval).value.obj
                    401: #define Z_OBJ_HANDLE(zval)             Z_OBJVAL(zval).handle
                    402: #define Z_OBJ_HT(zval)                 Z_OBJVAL(zval).handlers
                    403: #define Z_OBJCE(zval)                  zend_get_class_entry(&(zval) TSRMLS_CC)
                    404: #define Z_OBJPROP(zval)                        Z_OBJ_HT((zval))->get_properties(&(zval) TSRMLS_CC)
                    405: #define Z_OBJ_HANDLER(zval, hf) Z_OBJ_HT((zval))->hf
                    406: #define Z_RESVAL(zval)                 (zval).value.lval
                    407: #define Z_OBJDEBUG(zval,is_tmp)        (Z_OBJ_HANDLER((zval),get_debug_info)?Z_OBJ_HANDLER((zval),get_debug_info)(&(zval),&is_tmp TSRMLS_CC):(is_tmp=0,Z_OBJ_HANDLER((zval),get_properties)?Z_OBJPROP(zval):NULL))
                    408: 
                    409: #define Z_LVAL_P(zval_p)               Z_LVAL(*zval_p)
                    410: #define Z_BVAL_P(zval_p)               Z_BVAL(*zval_p)
                    411: #define Z_DVAL_P(zval_p)               Z_DVAL(*zval_p)
                    412: #define Z_STRVAL_P(zval_p)             Z_STRVAL(*zval_p)
                    413: #define Z_STRLEN_P(zval_p)             Z_STRLEN(*zval_p)
                    414: #define Z_ARRVAL_P(zval_p)             Z_ARRVAL(*zval_p)
                    415: #define Z_OBJPROP_P(zval_p)            Z_OBJPROP(*zval_p)
                    416: #define Z_OBJCE_P(zval_p)              Z_OBJCE(*zval_p)
                    417: #define Z_RESVAL_P(zval_p)             Z_RESVAL(*zval_p)
                    418: #define Z_OBJVAL_P(zval_p)             Z_OBJVAL(*zval_p)
                    419: #define Z_OBJ_HANDLE_P(zval_p) Z_OBJ_HANDLE(*zval_p)
                    420: #define Z_OBJ_HT_P(zval_p)             Z_OBJ_HT(*zval_p)
                    421: #define Z_OBJ_HANDLER_P(zval_p, h)     Z_OBJ_HANDLER(*zval_p, h)
                    422: #define Z_OBJDEBUG_P(zval_p,is_tmp)    Z_OBJDEBUG(*zval_p,is_tmp)
                    423: 
                    424: #define Z_LVAL_PP(zval_pp)             Z_LVAL(**zval_pp)
                    425: #define Z_BVAL_PP(zval_pp)             Z_BVAL(**zval_pp)
                    426: #define Z_DVAL_PP(zval_pp)             Z_DVAL(**zval_pp)
                    427: #define Z_STRVAL_PP(zval_pp)   Z_STRVAL(**zval_pp)
                    428: #define Z_STRLEN_PP(zval_pp)   Z_STRLEN(**zval_pp)
                    429: #define Z_ARRVAL_PP(zval_pp)   Z_ARRVAL(**zval_pp)
                    430: #define Z_OBJPROP_PP(zval_pp)  Z_OBJPROP(**zval_pp)
                    431: #define Z_OBJCE_PP(zval_pp)            Z_OBJCE(**zval_pp)
                    432: #define Z_RESVAL_PP(zval_pp)   Z_RESVAL(**zval_pp)
                    433: #define Z_OBJVAL_PP(zval_pp)   Z_OBJVAL(**zval_pp)
                    434: #define Z_OBJ_HANDLE_PP(zval_p)        Z_OBJ_HANDLE(**zval_p)
                    435: #define Z_OBJ_HT_PP(zval_p)            Z_OBJ_HT(**zval_p)
                    436: #define Z_OBJ_HANDLER_PP(zval_p, h)            Z_OBJ_HANDLER(**zval_p, h)
                    437: #define Z_OBJDEBUG_PP(zval_pp,is_tmp)  Z_OBJDEBUG(**zval_pp,is_tmp)
                    438: 
                    439: #define Z_TYPE(zval)           (zval).type
                    440: #define Z_TYPE_P(zval_p)       Z_TYPE(*zval_p)
                    441: #define Z_TYPE_PP(zval_pp)     Z_TYPE(**zval_pp)
                    442: 
                    443: #if HAVE_SETLOCALE && defined(ZEND_WIN32) && !defined(ZTS) && defined(_MSC_VER) && (_MSC_VER >= 1400)
                    444: /* This is performance improvement of tolower() on Windows and VC2005
                    445:  * Gives 10-18% on bench.php
                    446:  */
                    447: #define ZEND_USE_TOLOWER_L 1
                    448: #endif
                    449: 
                    450: #ifdef ZEND_USE_TOLOWER_L
                    451: ZEND_API void zend_update_current_locale(void);
                    452: #else
                    453: #define zend_update_current_locale()
                    454: #endif
                    455: 
1.1.1.2 ! misho     456: static zend_always_inline int fast_increment_function(zval *op1)
        !           457: {
        !           458:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           459: #if defined(__GNUC__) && defined(__i386__)
        !           460:                __asm__(
        !           461:                        "incl (%0)\n\t"
        !           462:                        "jno  0f\n\t"
        !           463:                        "movl $0x0, (%0)\n\t"
        !           464:                        "movl $0x41e00000, 0x4(%0)\n\t"
        !           465:                        "movb $0x2,0xc(%0)\n"
        !           466:                        "0:"
        !           467:                        :
        !           468:                        : "r"(op1));
        !           469: #elif defined(__GNUC__) && defined(__x86_64__)
        !           470:                __asm__(
        !           471:                        "incq (%0)\n\t"
        !           472:                        "jno  0f\n\t"
        !           473:                        "movl $0x0, (%0)\n\t"
        !           474:                        "movl $0x43e00000, 0x4(%0)\n\t"
        !           475:                        "movb $0x2,0x14(%0)\n"
        !           476:                        "0:"
        !           477:                        :
        !           478:                        : "r"(op1));
        !           479: #else
        !           480:                if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MAX)) {
        !           481:                        /* switch to double */
        !           482:                        Z_DVAL_P(op1) = (double)LONG_MAX + 1.0;
        !           483:                        Z_TYPE_P(op1) = IS_DOUBLE;
        !           484:                } else {
        !           485:                        Z_LVAL_P(op1)++;
        !           486:                }
        !           487: #endif
        !           488:                return SUCCESS;
        !           489:        }
        !           490:        return increment_function(op1);
        !           491: }
        !           492: 
        !           493: static zend_always_inline int fast_decrement_function(zval *op1)
        !           494: {
        !           495:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           496: #if defined(__GNUC__) && defined(__i386__)
        !           497:                __asm__(
        !           498:                        "decl (%0)\n\t"
        !           499:                        "jno  0f\n\t"
        !           500:                        "movl $0x00200000, (%0)\n\t"
        !           501:                        "movl $0xc1e00000, 0x4(%0)\n\t"
        !           502:                        "movb $0x2,0xc(%0)\n"
        !           503:                        "0:"
        !           504:                        :
        !           505:                        : "r"(op1));
        !           506: #elif defined(__GNUC__) && defined(__x86_64__)
        !           507:                __asm__(
        !           508:                        "decq (%0)\n\t"
        !           509:                        "jno  0f\n\t"
        !           510:                        "movl $0x00000000, (%0)\n\t"
        !           511:                        "movl $0xc3e00000, 0x4(%0)\n\t"
        !           512:                        "movb $0x2,0x14(%0)\n"
        !           513:                        "0:"
        !           514:                        :
        !           515:                        : "r"(op1));
        !           516: #else
        !           517:                if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MIN)) {
        !           518:                        /* switch to double */
        !           519:                        Z_DVAL_P(op1) = (double)LONG_MIN - 1.0;
        !           520:                        Z_TYPE_P(op1) = IS_DOUBLE;
        !           521:                } else {
        !           522:                        Z_LVAL_P(op1)--;
        !           523:                }
        !           524: #endif
        !           525:                return SUCCESS;
        !           526:        }
        !           527:        return decrement_function(op1);
        !           528: }
        !           529: 
        !           530: static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           531: {
        !           532:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           533:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           534: #if defined(__GNUC__) && defined(__i386__)
        !           535:                __asm__(
        !           536:                        "movl   (%1), %%eax\n\t"
        !           537:                        "addl   (%2), %%eax\n\t"
        !           538:                        "jo     0f\n\t"     
        !           539:                        "movl   %%eax, (%0)\n\t"
        !           540:                        "movb   $0x1,0xc(%0)\n\t"
        !           541:                        "jmp    1f\n"
        !           542:                        "0:\n\t"
        !           543:                        "fildl  (%1)\n\t"
        !           544:                        "fildl  (%2)\n\t"
        !           545:                        "faddp  %%st, %%st(1)\n\t"
        !           546:                        "movb   $0x2,0xc(%0)\n\t"
        !           547:                        "fstpl  (%0)\n"
        !           548:                        "1:"
        !           549:                        : 
        !           550:                        : "r"(result),
        !           551:                          "r"(op1),
        !           552:                          "r"(op2)
        !           553:                        : "eax");
        !           554: #elif defined(__GNUC__) && defined(__x86_64__)
        !           555:                __asm__(
        !           556:                        "movq   (%1), %%rax\n\t"
        !           557:                        "addq   (%2), %%rax\n\t"
        !           558:                        "jo     0f\n\t"     
        !           559:                        "movq   %%rax, (%0)\n\t"
        !           560:                        "movb   $0x1,0x14(%0)\n\t"
        !           561:                        "jmp    1f\n"
        !           562:                        "0:\n\t"
        !           563:                        "fildq  (%1)\n\t"
        !           564:                        "fildq  (%2)\n\t"
        !           565:                        "faddp  %%st, %%st(1)\n\t"
        !           566:                        "movb   $0x2,0x14(%0)\n\t"
        !           567:                        "fstpl  (%0)\n"
        !           568:                        "1:"
        !           569:                        : 
        !           570:                        : "r"(result),
        !           571:                          "r"(op1),
        !           572:                          "r"(op2)
        !           573:                        : "rax");
        !           574: #else
        !           575:                        Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2);
        !           576: 
        !           577:                        if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
        !           578:                                && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
        !           579:                                Z_DVAL_P(result) = (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2);
        !           580:                                Z_TYPE_P(result) = IS_DOUBLE;
        !           581:                        } else {
        !           582:                                Z_TYPE_P(result) = IS_LONG;
        !           583:                        }
        !           584: #endif
        !           585:                        return SUCCESS;
        !           586:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           587:                        Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2);
        !           588:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           589:                        return SUCCESS;
        !           590:                }
        !           591:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
        !           592:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           593:                        Z_DVAL_P(result) = Z_DVAL_P(op1) + Z_DVAL_P(op2);
        !           594:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           595:                        return SUCCESS;
        !           596:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           597:                        Z_DVAL_P(result) = Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2));
        !           598:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           599:                        return SUCCESS;
        !           600:                }
        !           601:        }
        !           602:        return add_function(result, op1, op2 TSRMLS_CC);
        !           603: }
        !           604: 
        !           605: static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           606: {
        !           607:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           608:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           609: #if defined(__GNUC__) && defined(__i386__)
        !           610:                __asm__(
        !           611:                        "movl   (%1), %%eax\n\t"
        !           612:                        "subl   (%2), %%eax\n\t"
        !           613:                        "jo     0f\n\t"     
        !           614:                        "movl   %%eax, (%0)\n\t"
        !           615:                        "movb   $0x1,0xc(%0)\n\t"
        !           616:                        "jmp    1f\n"
        !           617:                        "0:\n\t"
        !           618:                        "fildl  (%2)\n\t"
        !           619:                        "fildl  (%1)\n\t"
        !           620: #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
        !           621:                        "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
        !           622: #else
        !           623:                        "fsubp  %%st, %%st(1)\n\t"
        !           624: #endif
        !           625:                        "movb   $0x2,0xc(%0)\n\t"
        !           626:                        "fstpl  (%0)\n"
        !           627:                        "1:"
        !           628:                        : 
        !           629:                        : "r"(result),
        !           630:                          "r"(op1),
        !           631:                          "r"(op2)
        !           632:                        : "eax");
        !           633: #elif defined(__GNUC__) && defined(__x86_64__)
        !           634:                __asm__(
        !           635:                        "movq   (%1), %%rax\n\t"
        !           636:                        "subq   (%2), %%rax\n\t"
        !           637:                        "jo     0f\n\t"     
        !           638:                        "movq   %%rax, (%0)\n\t"
        !           639:                        "movb   $0x1,0x14(%0)\n\t"
        !           640:                        "jmp    1f\n"
        !           641:                        "0:\n\t"
        !           642:                        "fildq  (%2)\n\t"
        !           643:                        "fildq  (%1)\n\t"
        !           644: #if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
        !           645:                        "fsubp  %%st(1), %%st\n\t"  /* LLVM bug #9164 */
        !           646: #else
        !           647:                        "fsubp  %%st, %%st(1)\n\t"
        !           648: #endif
        !           649:                        "movb   $0x2,0x14(%0)\n\t"
        !           650:                        "fstpl  (%0)\n"
        !           651:                        "1:"
        !           652:                        : 
        !           653:                        : "r"(result),
        !           654:                          "r"(op1),
        !           655:                          "r"(op2)
        !           656:                        : "rax");
        !           657: #else
        !           658:                        Z_LVAL_P(result) = Z_LVAL_P(op1) - Z_LVAL_P(op2);
        !           659: 
        !           660:                        if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
        !           661:                                && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
        !           662:                                Z_DVAL_P(result) = (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2);
        !           663:                                Z_TYPE_P(result) = IS_DOUBLE;
        !           664:                        } else {
        !           665:                                Z_TYPE_P(result) = IS_LONG;
        !           666:                        }
        !           667: #endif
        !           668:                        return SUCCESS;
        !           669:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           670:                        Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2);
        !           671:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           672:                        return SUCCESS;
        !           673:                }
        !           674:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
        !           675:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           676:                        Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
        !           677:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           678:                        return SUCCESS;
        !           679:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           680:                        Z_DVAL_P(result) = Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2));
        !           681:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           682:                        return SUCCESS;
        !           683:                }
        !           684:        }
        !           685:        return sub_function(result, op1, op2 TSRMLS_CC);
        !           686: }
        !           687: 
        !           688: static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           689: {
        !           690:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           691:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           692:                        long overflow;
        !           693: 
        !           694:                        ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
        !           695:                        Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG;
        !           696:                        return SUCCESS;
        !           697:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           698:                        Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2);
        !           699:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           700:                        return SUCCESS;
        !           701:                }
        !           702:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
        !           703:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           704:                        Z_DVAL_P(result) = Z_DVAL_P(op1) * Z_DVAL_P(op2);
        !           705:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           706:                        return SUCCESS;
        !           707:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           708:                        Z_DVAL_P(result) = Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2));
        !           709:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           710:                        return SUCCESS;
        !           711:                }
        !           712:        }
        !           713:        return mul_function(result, op1, op2 TSRMLS_CC);
        !           714: }
        !           715: 
        !           716: static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           717: {
        !           718:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && 0) {
        !           719:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           720:                        if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
        !           721:                                zend_error(E_WARNING, "Division by zero");
        !           722:                                Z_LVAL_P(result) = 0;
        !           723:                                Z_TYPE_P(result) = IS_BOOL;
        !           724:                                return FAILURE;
        !           725:                        } else if (UNEXPECTED(Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN)) {
        !           726:                                /* Prevent overflow error/crash */
        !           727:                                Z_DVAL_P(result) = (double) LONG_MIN / -1;
        !           728:                                Z_TYPE_P(result) = IS_DOUBLE;
        !           729:                        } else if (EXPECTED(Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0)) {
        !           730:                                /* integer */
        !           731:                                Z_LVAL_P(result) = Z_LVAL_P(op1) / Z_LVAL_P(op2);
        !           732:                                Z_TYPE_P(result) = IS_LONG;
        !           733:                        } else {
        !           734:                                Z_DVAL_P(result) = ((double) Z_LVAL_P(op1)) / ((double)Z_LVAL_P(op2));
        !           735:                                Z_TYPE_P(result) = IS_DOUBLE;
        !           736:                        }
        !           737:                        return SUCCESS;
        !           738:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           739:                        if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
        !           740:                                zend_error(E_WARNING, "Division by zero");
        !           741:                                Z_LVAL_P(result) = 0;
        !           742:                                Z_TYPE_P(result) = IS_BOOL;
        !           743:                                return FAILURE;
        !           744:                        }
        !           745:                        Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) / Z_DVAL_P(op2);
        !           746:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           747:                        return SUCCESS;
        !           748:                }
        !           749:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE) && 0) {
        !           750:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           751:                        if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
        !           752:                                zend_error(E_WARNING, "Division by zero");
        !           753:                                Z_LVAL_P(result) = 0;
        !           754:                                Z_TYPE_P(result) = IS_BOOL;
        !           755:                                return FAILURE;
        !           756:                        }
        !           757:                        Z_DVAL_P(result) = Z_DVAL_P(op1) / Z_DVAL_P(op2);
        !           758:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           759:                        return SUCCESS;
        !           760:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           761:                        if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
        !           762:                                zend_error(E_WARNING, "Division by zero");
        !           763:                                Z_LVAL_P(result) = 0;
        !           764:                                Z_TYPE_P(result) = IS_BOOL;
        !           765:                                return FAILURE;
        !           766:                        }
        !           767:                        Z_DVAL_P(result) = Z_DVAL_P(op1) / ((double)Z_LVAL_P(op2));
        !           768:                        Z_TYPE_P(result) = IS_DOUBLE;
        !           769:                        return SUCCESS;
        !           770:                }
        !           771:        }
        !           772:        return div_function(result, op1, op2 TSRMLS_CC);
        !           773: }
        !           774: 
        !           775: static zend_always_inline int fast_mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           776: {
        !           777:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           778:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           779:                        if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
        !           780:                                zend_error(E_WARNING, "Division by zero");
        !           781:                                Z_LVAL_P(result) = 0;
        !           782:                                Z_TYPE_P(result) = IS_BOOL;
        !           783:                                return FAILURE;
        !           784:                        } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
        !           785:                                /* Prevent overflow error/crash if op1==LONG_MIN */
        !           786:                                Z_LVAL_P(result) = 0;
        !           787:                                Z_TYPE_P(result) = IS_LONG;
        !           788:                                return SUCCESS;
        !           789:                        }
        !           790:                        Z_LVAL_P(result) = Z_LVAL_P(op1) % Z_LVAL_P(op2);
        !           791:                        Z_TYPE_P(result) = IS_LONG;
        !           792:                        return SUCCESS;
        !           793:                }
        !           794:        }
        !           795:        return mod_function(result, op1, op2 TSRMLS_CC);
        !           796: }
        !           797: 
        !           798: static zend_always_inline int fast_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           799: {
        !           800:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           801:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           802:                        return Z_LVAL_P(op1) == Z_LVAL_P(op2);
        !           803:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           804:                        return ((double)Z_LVAL_P(op1)) == Z_DVAL_P(op2);
        !           805:                }
        !           806:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
        !           807:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           808:                        return Z_DVAL_P(op1) == Z_DVAL_P(op2);
        !           809:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           810:                        return Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2));
        !           811:                }
        !           812:        }
        !           813:        compare_function(result, op1, op2 TSRMLS_CC);
        !           814:        return Z_LVAL_P(result) == 0;
        !           815: }
        !           816: 
        !           817: static zend_always_inline int fast_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           818: {
        !           819:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           820:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           821:                        return Z_LVAL_P(op1) != Z_LVAL_P(op2);
        !           822:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           823:                        return ((double)Z_LVAL_P(op1)) != Z_DVAL_P(op2);
        !           824:                }
        !           825:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
        !           826:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           827:                        return Z_DVAL_P(op1) != Z_DVAL_P(op2);
        !           828:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           829:                        return Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2));
        !           830:                }
        !           831:        }
        !           832:        compare_function(result, op1, op2 TSRMLS_CC);
        !           833:        return Z_LVAL_P(result) != 0;
        !           834: }
        !           835: 
        !           836: static zend_always_inline int fast_is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           837: {
        !           838:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           839:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           840:                        return Z_LVAL_P(op1) < Z_LVAL_P(op2);
        !           841:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           842:                        return ((double)Z_LVAL_P(op1)) < Z_DVAL_P(op2);
        !           843:                }
        !           844:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
        !           845:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           846:                        return Z_DVAL_P(op1) < Z_DVAL_P(op2);
        !           847:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           848:                        return Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2));
        !           849:                }
        !           850:        }
        !           851:        compare_function(result, op1, op2 TSRMLS_CC);
        !           852:        return Z_LVAL_P(result) < 0;
        !           853: }
        !           854: 
        !           855: static zend_always_inline int fast_is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
        !           856: {
        !           857:        if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
        !           858:                if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           859:                        return Z_LVAL_P(op1) <= Z_LVAL_P(op2);
        !           860:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           861:                        return ((double)Z_LVAL_P(op1)) <= Z_DVAL_P(op2);
        !           862:                }
        !           863:        } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
        !           864:                if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
        !           865:                        return Z_DVAL_P(op1) <= Z_DVAL_P(op2);
        !           866:                } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
        !           867:                        return Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2));
        !           868:                }
        !           869:        }
        !           870:        compare_function(result, op1, op2 TSRMLS_CC);
        !           871:        return Z_LVAL_P(result) <= 0;
        !           872: }
        !           873: 
1.1       misho     874: #endif
                    875: 
                    876: /*
                    877:  * Local variables:
                    878:  * tab-width: 4
                    879:  * c-basic-offset: 4
                    880:  * indent-tabs-mode: t
                    881:  * End:
                    882:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>