version 1.1.1.1, 2012/02/21 23:47:52
|
version 1.1.1.2, 2012/05/29 12:34:36
|
Line 31
|
Line 31
|
#endif |
#endif |
|
|
#include "zend_strtod.h" |
#include "zend_strtod.h" |
|
#include "zend_multiply.h" |
|
|
#if 0&&HAVE_BCMATH |
#if 0&&HAVE_BCMATH |
#include "ext/bcmath/libbcmath/src/bcmath.h" |
#include "ext/bcmath/libbcmath/src/bcmath.h" |
#endif |
#endif |
|
|
|
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1)) |
|
|
BEGIN_EXTERN_C() |
BEGIN_EXTERN_C() |
ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
Line 167 check_digits:
|
Line 170 check_digits:
|
} |
} |
} else if (!(digits < SIZEOF_LONG * 2 || (digits == SIZEOF_LONG * 2 && ptr[-digits] <= '7'))) { |
} else if (!(digits < SIZEOF_LONG * 2 || (digits == SIZEOF_LONG * 2 && ptr[-digits] <= '7'))) { |
if (dval) { |
if (dval) { |
local_dval = zend_hex_strtod(str, (char **)&ptr); | local_dval = zend_hex_strtod(str, &ptr); |
} |
} |
type = IS_DOUBLE; |
type = IS_DOUBLE; |
} |
} |
Line 178 process_double:
|
Line 181 process_double:
|
/* If there's a dval, do the conversion; else continue checking |
/* If there's a dval, do the conversion; else continue checking |
* the digits if we need to check for a full match */ |
* the digits if we need to check for a full match */ |
if (dval) { |
if (dval) { |
local_dval = zend_strtod(str, (char **)&ptr); | local_dval = zend_strtod(str, &ptr); |
} else if (allow_errors != 1 && dp_or_e != -1) { |
} else if (allow_errors != 1 && dp_or_e != -1) { |
dp_or_e = (*ptr++ == '.') ? 1 : 2; |
dp_or_e = (*ptr++ == '.') ? 1 : 2; |
goto check_digits; |
goto check_digits; |
Line 256 zend_memnstr(char *haystack, char *needle, int needle_
|
Line 259 zend_memnstr(char *haystack, char *needle, int needle_
|
return NULL; |
return NULL; |
} |
} |
|
|
static inline void *zend_memrchr(const void *s, int c, size_t n) | static inline const void *zend_memrchr(const void *s, int c, size_t n) |
{ |
{ |
register unsigned char *e; | register const unsigned char *e; |
|
|
if (n <= 0) { |
if (n <= 0) { |
return NULL; |
return NULL; |
} |
} |
|
|
for (e = (unsigned char *)s + n - 1; e >= (unsigned char *)s; e--) { | for (e = (const unsigned char *)s + n - 1; e >= (const unsigned char *)s; e--) { |
if (*e == (unsigned char)c) { | if (*e == (const unsigned char)c) { |
return (void *)e; | return (const void *)e; |
} |
} |
} |
} |
|
|
Line 298 ZEND_API double zend_string_to_double(const char *numb
|
Line 301 ZEND_API double zend_string_to_double(const char *numb
|
ZEND_API int zval_is_true(zval *op); |
ZEND_API int zval_is_true(zval *op); |
ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
|
ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC); |
ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int string_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
|
ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
#if HAVE_STRCOLL |
#if HAVE_STRCOLL |
ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); |
#endif |
#endif |
Line 447 ZEND_API void zend_update_current_locale(void);
|
Line 452 ZEND_API void zend_update_current_locale(void);
|
#else |
#else |
#define zend_update_current_locale() |
#define zend_update_current_locale() |
#endif |
#endif |
|
|
|
static zend_always_inline int fast_increment_function(zval *op1) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
#if defined(__GNUC__) && defined(__i386__) |
|
__asm__( |
|
"incl (%0)\n\t" |
|
"jno 0f\n\t" |
|
"movl $0x0, (%0)\n\t" |
|
"movl $0x41e00000, 0x4(%0)\n\t" |
|
"movb $0x2,0xc(%0)\n" |
|
"0:" |
|
: |
|
: "r"(op1)); |
|
#elif defined(__GNUC__) && defined(__x86_64__) |
|
__asm__( |
|
"incq (%0)\n\t" |
|
"jno 0f\n\t" |
|
"movl $0x0, (%0)\n\t" |
|
"movl $0x43e00000, 0x4(%0)\n\t" |
|
"movb $0x2,0x14(%0)\n" |
|
"0:" |
|
: |
|
: "r"(op1)); |
|
#else |
|
if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MAX)) { |
|
/* switch to double */ |
|
Z_DVAL_P(op1) = (double)LONG_MAX + 1.0; |
|
Z_TYPE_P(op1) = IS_DOUBLE; |
|
} else { |
|
Z_LVAL_P(op1)++; |
|
} |
|
#endif |
|
return SUCCESS; |
|
} |
|
return increment_function(op1); |
|
} |
|
|
|
static zend_always_inline int fast_decrement_function(zval *op1) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
#if defined(__GNUC__) && defined(__i386__) |
|
__asm__( |
|
"decl (%0)\n\t" |
|
"jno 0f\n\t" |
|
"movl $0x00200000, (%0)\n\t" |
|
"movl $0xc1e00000, 0x4(%0)\n\t" |
|
"movb $0x2,0xc(%0)\n" |
|
"0:" |
|
: |
|
: "r"(op1)); |
|
#elif defined(__GNUC__) && defined(__x86_64__) |
|
__asm__( |
|
"decq (%0)\n\t" |
|
"jno 0f\n\t" |
|
"movl $0x00000000, (%0)\n\t" |
|
"movl $0xc3e00000, 0x4(%0)\n\t" |
|
"movb $0x2,0x14(%0)\n" |
|
"0:" |
|
: |
|
: "r"(op1)); |
|
#else |
|
if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MIN)) { |
|
/* switch to double */ |
|
Z_DVAL_P(op1) = (double)LONG_MIN - 1.0; |
|
Z_TYPE_P(op1) = IS_DOUBLE; |
|
} else { |
|
Z_LVAL_P(op1)--; |
|
} |
|
#endif |
|
return SUCCESS; |
|
} |
|
return decrement_function(op1); |
|
} |
|
|
|
static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
#if defined(__GNUC__) && defined(__i386__) |
|
__asm__( |
|
"movl (%1), %%eax\n\t" |
|
"addl (%2), %%eax\n\t" |
|
"jo 0f\n\t" |
|
"movl %%eax, (%0)\n\t" |
|
"movb $0x1,0xc(%0)\n\t" |
|
"jmp 1f\n" |
|
"0:\n\t" |
|
"fildl (%1)\n\t" |
|
"fildl (%2)\n\t" |
|
"faddp %%st, %%st(1)\n\t" |
|
"movb $0x2,0xc(%0)\n\t" |
|
"fstpl (%0)\n" |
|
"1:" |
|
: |
|
: "r"(result), |
|
"r"(op1), |
|
"r"(op2) |
|
: "eax"); |
|
#elif defined(__GNUC__) && defined(__x86_64__) |
|
__asm__( |
|
"movq (%1), %%rax\n\t" |
|
"addq (%2), %%rax\n\t" |
|
"jo 0f\n\t" |
|
"movq %%rax, (%0)\n\t" |
|
"movb $0x1,0x14(%0)\n\t" |
|
"jmp 1f\n" |
|
"0:\n\t" |
|
"fildq (%1)\n\t" |
|
"fildq (%2)\n\t" |
|
"faddp %%st, %%st(1)\n\t" |
|
"movb $0x2,0x14(%0)\n\t" |
|
"fstpl (%0)\n" |
|
"1:" |
|
: |
|
: "r"(result), |
|
"r"(op1), |
|
"r"(op2) |
|
: "rax"); |
|
#else |
|
Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2); |
|
|
|
if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK) |
|
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) { |
|
Z_DVAL_P(result) = (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
} else { |
|
Z_TYPE_P(result) = IS_LONG; |
|
} |
|
#endif |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) + Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} |
|
return add_function(result, op1, op2 TSRMLS_CC); |
|
} |
|
|
|
static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
#if defined(__GNUC__) && defined(__i386__) |
|
__asm__( |
|
"movl (%1), %%eax\n\t" |
|
"subl (%2), %%eax\n\t" |
|
"jo 0f\n\t" |
|
"movl %%eax, (%0)\n\t" |
|
"movb $0x1,0xc(%0)\n\t" |
|
"jmp 1f\n" |
|
"0:\n\t" |
|
"fildl (%2)\n\t" |
|
"fildl (%1)\n\t" |
|
#if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10)) |
|
"fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */ |
|
#else |
|
"fsubp %%st, %%st(1)\n\t" |
|
#endif |
|
"movb $0x2,0xc(%0)\n\t" |
|
"fstpl (%0)\n" |
|
"1:" |
|
: |
|
: "r"(result), |
|
"r"(op1), |
|
"r"(op2) |
|
: "eax"); |
|
#elif defined(__GNUC__) && defined(__x86_64__) |
|
__asm__( |
|
"movq (%1), %%rax\n\t" |
|
"subq (%2), %%rax\n\t" |
|
"jo 0f\n\t" |
|
"movq %%rax, (%0)\n\t" |
|
"movb $0x1,0x14(%0)\n\t" |
|
"jmp 1f\n" |
|
"0:\n\t" |
|
"fildq (%2)\n\t" |
|
"fildq (%1)\n\t" |
|
#if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10)) |
|
"fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */ |
|
#else |
|
"fsubp %%st, %%st(1)\n\t" |
|
#endif |
|
"movb $0x2,0x14(%0)\n\t" |
|
"fstpl (%0)\n" |
|
"1:" |
|
: |
|
: "r"(result), |
|
"r"(op1), |
|
"r"(op2) |
|
: "rax"); |
|
#else |
|
Z_LVAL_P(result) = Z_LVAL_P(op1) - Z_LVAL_P(op2); |
|
|
|
if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK) |
|
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) { |
|
Z_DVAL_P(result) = (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
} else { |
|
Z_TYPE_P(result) = IS_LONG; |
|
} |
|
#endif |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} |
|
return sub_function(result, op1, op2 TSRMLS_CC); |
|
} |
|
|
|
static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
long overflow; |
|
|
|
ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); |
|
Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG; |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) * Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} |
|
return mul_function(result, op1, op2 TSRMLS_CC); |
|
} |
|
|
|
static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && 0) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { |
|
zend_error(E_WARNING, "Division by zero"); |
|
Z_LVAL_P(result) = 0; |
|
Z_TYPE_P(result) = IS_BOOL; |
|
return FAILURE; |
|
} else if (UNEXPECTED(Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN)) { |
|
/* Prevent overflow error/crash */ |
|
Z_DVAL_P(result) = (double) LONG_MIN / -1; |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
} else if (EXPECTED(Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0)) { |
|
/* integer */ |
|
Z_LVAL_P(result) = Z_LVAL_P(op1) / Z_LVAL_P(op2); |
|
Z_TYPE_P(result) = IS_LONG; |
|
} else { |
|
Z_DVAL_P(result) = ((double) Z_LVAL_P(op1)) / ((double)Z_LVAL_P(op2)); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
} |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
if (UNEXPECTED(Z_DVAL_P(op2) == 0)) { |
|
zend_error(E_WARNING, "Division by zero"); |
|
Z_LVAL_P(result) = 0; |
|
Z_TYPE_P(result) = IS_BOOL; |
|
return FAILURE; |
|
} |
|
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) / Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE) && 0) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
if (UNEXPECTED(Z_DVAL_P(op2) == 0)) { |
|
zend_error(E_WARNING, "Division by zero"); |
|
Z_LVAL_P(result) = 0; |
|
Z_TYPE_P(result) = IS_BOOL; |
|
return FAILURE; |
|
} |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) / Z_DVAL_P(op2); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { |
|
zend_error(E_WARNING, "Division by zero"); |
|
Z_LVAL_P(result) = 0; |
|
Z_TYPE_P(result) = IS_BOOL; |
|
return FAILURE; |
|
} |
|
Z_DVAL_P(result) = Z_DVAL_P(op1) / ((double)Z_LVAL_P(op2)); |
|
Z_TYPE_P(result) = IS_DOUBLE; |
|
return SUCCESS; |
|
} |
|
} |
|
return div_function(result, op1, op2 TSRMLS_CC); |
|
} |
|
|
|
static zend_always_inline int fast_mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { |
|
zend_error(E_WARNING, "Division by zero"); |
|
Z_LVAL_P(result) = 0; |
|
Z_TYPE_P(result) = IS_BOOL; |
|
return FAILURE; |
|
} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { |
|
/* Prevent overflow error/crash if op1==LONG_MIN */ |
|
Z_LVAL_P(result) = 0; |
|
Z_TYPE_P(result) = IS_LONG; |
|
return SUCCESS; |
|
} |
|
Z_LVAL_P(result) = Z_LVAL_P(op1) % Z_LVAL_P(op2); |
|
Z_TYPE_P(result) = IS_LONG; |
|
return SUCCESS; |
|
} |
|
} |
|
return mod_function(result, op1, op2 TSRMLS_CC); |
|
} |
|
|
|
static zend_always_inline int fast_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_LVAL_P(op1) == Z_LVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return ((double)Z_LVAL_P(op1)) == Z_DVAL_P(op2); |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return Z_DVAL_P(op1) == Z_DVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)); |
|
} |
|
} |
|
compare_function(result, op1, op2 TSRMLS_CC); |
|
return Z_LVAL_P(result) == 0; |
|
} |
|
|
|
static zend_always_inline int fast_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_LVAL_P(op1) != Z_LVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return ((double)Z_LVAL_P(op1)) != Z_DVAL_P(op2); |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return Z_DVAL_P(op1) != Z_DVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)); |
|
} |
|
} |
|
compare_function(result, op1, op2 TSRMLS_CC); |
|
return Z_LVAL_P(result) != 0; |
|
} |
|
|
|
static zend_always_inline int fast_is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_LVAL_P(op1) < Z_LVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return ((double)Z_LVAL_P(op1)) < Z_DVAL_P(op2); |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return Z_DVAL_P(op1) < Z_DVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)); |
|
} |
|
} |
|
compare_function(result, op1, op2 TSRMLS_CC); |
|
return Z_LVAL_P(result) < 0; |
|
} |
|
|
|
static zend_always_inline int fast_is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
{ |
|
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_LVAL_P(op1) <= Z_LVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return ((double)Z_LVAL_P(op1)) <= Z_DVAL_P(op2); |
|
} |
|
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { |
|
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { |
|
return Z_DVAL_P(op1) <= Z_DVAL_P(op2); |
|
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { |
|
return Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)); |
|
} |
|
} |
|
compare_function(result, op1, op2 TSRMLS_CC); |
|
return Z_LVAL_P(result) <= 0; |
|
} |
|
|
#endif |
#endif |
|
|