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

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

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