|
|
|
@ -30,7 +30,6 @@ |
|
|
|
#include "zend_multiply.h" |
|
|
|
#include "zend_strtod.h" |
|
|
|
#include "zend_exceptions.h" |
|
|
|
#include "zend_float.h" |
|
|
|
|
|
|
|
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1)) |
|
|
|
|
|
|
|
@ -742,7 +741,6 @@ ZEND_API void multi_convert_to_string_ex(int argc, ...) |
|
|
|
|
|
|
|
ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
{ |
|
|
|
ZEND_FLOAT_DECLARE |
|
|
|
zval op1_copy, op2_copy; |
|
|
|
int converted = 0; |
|
|
|
|
|
|
|
@ -755,9 +753,7 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK) |
|
|
|
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) { |
|
|
|
|
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
} else { |
|
|
|
ZVAL_LONG(result, lval); |
|
|
|
} |
|
|
|
@ -765,21 +761,15 @@ ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
} |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_LONG, IS_DOUBLE): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_DOUBLE, IS_LONG): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_ARRAY, IS_ARRAY): { |
|
|
|
@ -813,7 +803,6 @@ 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_FLOAT_DECLARE |
|
|
|
zval op1_copy, op2_copy; |
|
|
|
int converted = 0; |
|
|
|
|
|
|
|
@ -826,9 +815,7 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK) |
|
|
|
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) { |
|
|
|
|
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
} else { |
|
|
|
ZVAL_LONG(result, lval); |
|
|
|
} |
|
|
|
@ -836,21 +823,15 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
|
|
|
|
} |
|
|
|
case TYPE_PAIR(IS_LONG, IS_DOUBLE): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_DOUBLE, IS_LONG): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
default: |
|
|
|
@ -869,7 +850,6 @@ ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
|
|
|
|
ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
{ |
|
|
|
ZEND_FLOAT_DECLARE |
|
|
|
zval op1_copy, op2_copy; |
|
|
|
int converted = 0; |
|
|
|
|
|
|
|
@ -878,29 +858,21 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
case TYPE_PAIR(IS_LONG, IS_LONG): { |
|
|
|
long overflow; |
|
|
|
|
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1),Z_LVAL_P(op2), Z_LVAL_P(result),Z_DVAL_P(result),overflow); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG; |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
} |
|
|
|
case TYPE_PAIR(IS_LONG, IS_DOUBLE): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_DOUBLE, IS_LONG): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
default: |
|
|
|
@ -918,7 +890,6 @@ ZEND_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
|
|
|
|
ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
{ |
|
|
|
ZEND_FLOAT_DECLARE |
|
|
|
zval op1_copy, op2_copy; |
|
|
|
int converted = 0; |
|
|
|
|
|
|
|
@ -931,17 +902,13 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
return FAILURE; /* division by zero */ |
|
|
|
} else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) { |
|
|
|
/* Prevent overflow error/crash */ |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, (double) LONG_MIN / -1); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
} |
|
|
|
if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */ |
|
|
|
ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2)); |
|
|
|
} else { |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
} |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
@ -951,9 +918,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
ZVAL_BOOL(result, 0); |
|
|
|
return FAILURE; /* division by zero */ |
|
|
|
} |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_LONG, IS_DOUBLE): |
|
|
|
@ -962,9 +927,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
ZVAL_BOOL(result, 0); |
|
|
|
return FAILURE; /* division by zero */ |
|
|
|
} |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): |
|
|
|
@ -973,9 +936,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) |
|
|
|
ZVAL_BOOL(result, 0); |
|
|
|
return FAILURE; /* division by zero */ |
|
|
|
} |
|
|
|
ZEND_FLOAT_ENSURE(); |
|
|
|
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2)); |
|
|
|
ZEND_FLOAT_RESTORE(); |
|
|
|
return SUCCESS; |
|
|
|
|
|
|
|
default: |
|
|
|
|