Fixed floating point mathematic speed degradation (Christian)

This commit is contained in:
Dmitry Stogov 2009-03-18 10:18:10 +00:00
parent d3b42700a0
commit 31c0af245e
11 changed files with 93 additions and 65 deletions

View file

@ -17,7 +17,7 @@ libZend_la_SOURCES=\
zend_objects_API.c zend_ts_hash.c zend_stream.c \ zend_objects_API.c zend_ts_hash.c zend_stream.c \
zend_default_classes.c \ zend_default_classes.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c \
zend_strtod.c zend_closures.c zend_strtod.c zend_closures.c zend_float.c
libZend_la_LDFLAGS = libZend_la_LDFLAGS =
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@ libZend_la_LIBADD = @ZEND_EXTRA_LIBS@

View file

@ -155,6 +155,10 @@ SOURCE=.\zend_extensions.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\zend_float.c
# End Source File
# Begin Source File
SOURCE=.\zend_hash.c SOURCE=.\zend_hash.c
# End Source File # End Source File
# Begin Source File # Begin Source File

View file

@ -549,6 +549,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS
EG(current_execute_data) = NULL; EG(current_execute_data) = NULL;
EG(current_module) = NULL; EG(current_module) = NULL;
EG(exit_status) = 0; EG(exit_status) = 0;
EG(saved_fpu_cw) = NULL;
EG(active) = 0; EG(active) = 0;
} }
/* }}} */ /* }}} */

View file

@ -123,6 +123,8 @@ static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {
void init_executor(TSRMLS_D) /* {{{ */ void init_executor(TSRMLS_D) /* {{{ */
{ {
zend_init_fpu(TSRMLS_C);
INIT_ZVAL(EG(uninitialized_zval)); INIT_ZVAL(EG(uninitialized_zval));
/* trick to make uninitialized_zval never be modified, passed by ref, etc. */ /* trick to make uninitialized_zval never be modified, passed by ref, etc. */
Z_ADDREF(EG(uninitialized_zval)); Z_ADDREF(EG(uninitialized_zval));
@ -331,6 +333,9 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
FREE_HASHTABLE(EG(in_autoload)); FREE_HASHTABLE(EG(in_autoload));
} }
} zend_end_try(); } zend_end_try();
zend_shutdown_fpu(TSRMLS_C);
EG(active) = 0; EG(active) = 0;
} }
/* }}} */ /* }}} */

View file

@ -21,10 +21,12 @@
#ifndef ZEND_FLOAT_H #ifndef ZEND_FLOAT_H
#define ZEND_FLOAT_H #define ZEND_FLOAT_H
#define ZEND_FLOAT_DECLARE XPFPA_DECLARE /*
#define ZEND_FLOAT_ENSURE() XPFPA_SWITCH_DOUBLE() Define functions for FP initialization and de-initialization.
#define ZEND_FLOAT_RESTORE() XPFPA_RESTORE() */
#define ZEND_FLOAT_RETURN(val) XPFPA_RETURN_DOUBLE(val) extern ZEND_API void zend_init_fpu(TSRMLS_D);
extern ZEND_API void zend_shutdown_fpu(TSRMLS_D);
extern ZEND_API void zend_ensure_fpu_mode(TSRMLS_D);
/* Copy of the contents of xpfpa.h (which is under public domain) /* Copy of the contents of xpfpa.h (which is under public domain)
See http://wiki.php.net/rfc/rounding for details. See http://wiki.php.net/rfc/rounding for details.
@ -45,7 +47,7 @@
For further details, please visit: For further details, please visit:
http://www.christian-seiler.de/projekte/fpmath/ http://www.christian-seiler.de/projekte/fpmath/
Version: 20081026 */ Version: 20090317 */
/* /*
Implementation notes: Implementation notes:
@ -69,11 +71,8 @@
/* MSVC detection (MSVC people usually don't use autoconf) */ /* MSVC detection (MSVC people usually don't use autoconf) */
#ifdef _MSC_VER #ifdef _MSC_VER
# if _MSC_VER >= 1500 # if _MSC_VER >= 1500
/* Disable it, it slowdowns the floating operation more than
anything else, by a factor 3 (using Bench.php (mandel and
mandel2 for example)*/
/* Visual C++ 2008 or higher, supports _controlfp_s */ /* Visual C++ 2008 or higher, supports _controlfp_s */
/*# define HAVE__CONTROLFP_S */ # define HAVE__CONTROLFP_S
# else # else
/* Visual C++ (up to 2005), supports _controlfp */ /* Visual C++ (up to 2005), supports _controlfp */
# define HAVE__CONTROLFP # define HAVE__CONTROLFP
@ -87,6 +86,19 @@
/* float.h defines _controlfp_s */ /* float.h defines _controlfp_s */
# include <float.h> # include <float.h>
# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
unsigned int
# define XPFPA_STORE_CW(vptr) do { \
_controlfp_s((unsigned int *)(vptr), 0, 0); \
} while (0)
# define XPFPA_RESTORE_CW(vptr) do { \
unsigned int _xpfpa_fpu_cw; \
_controlfp_s(&_xpfpa_fpu_cw, *((unsigned int *)(vptr)), _MCW_PC); \
} while (0)
# define XPFPA_DECLARE \ # define XPFPA_DECLARE \
unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw; unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
@ -141,6 +153,18 @@
# define XPFPA_DECLARE \ # define XPFPA_DECLARE \
unsigned int _xpfpa_fpu_oldcw; unsigned int _xpfpa_fpu_oldcw;
# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
unsigned int
# define XPFPA_STORE_CW(vptr) do { \
*((unsigned int *)(vptr)) = _controlfp(0, 0); \
} while (0)
# define XPFPA_RESTORE_CW(vptr) do { \
_controlfp(*((unsigned int *)(vptr)), _MCW_PC); \
} while (0)
# define XPFPA_SWITCH_DOUBLE() do { \ # define XPFPA_SWITCH_DOUBLE() do { \
_xpfpa_fpu_oldcw = _controlfp(0, 0); \ _xpfpa_fpu_oldcw = _controlfp(0, 0); \
_controlfp(_PC_53, _MCW_PC); \ _controlfp(_PC_53, _MCW_PC); \
@ -188,6 +212,18 @@
# define XPFPA_DECLARE \ # define XPFPA_DECLARE \
fpu_control_t _xpfpa_fpu_oldcw, _xpfpa_fpu_cw; fpu_control_t _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
fpu_control_t
# define XPFPA_STORE_CW(vptr) do { \
_FPU_GETCW((*((fpu_control_t *)(vptr)))); \
} while (0)
# define XPFPA_RESTORE_CW(vptr) do { \
_FPU_SETCW((*((fpu_control_t *)(vptr)))); \
} while (0)
# define XPFPA_SWITCH_DOUBLE() do { \ # define XPFPA_SWITCH_DOUBLE() do { \
_FPU_GETCW(_xpfpa_fpu_oldcw); \ _FPU_GETCW(_xpfpa_fpu_oldcw); \
_xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; \ _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; \
@ -235,6 +271,18 @@
# define XPFPA_DECLARE \ # define XPFPA_DECLARE \
fp_prec_t _xpfpa_fpu_oldprec; fp_prec_t _xpfpa_fpu_oldprec;
# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
fp_prec_t
# define XPFPA_STORE_CW(vptr) do { \
*((fp_prec_t *)(vptr)) = fpgetprec(); \
} while (0)
# define XPFPA_RESTORE_CW(vptr) do { \
fpsetprec(*((fp_prec_t *)(vptr))); \
} while (0)
# define XPFPA_SWITCH_DOUBLE() do { \ # define XPFPA_SWITCH_DOUBLE() do { \
_xpfpa_fpu_oldprec = fpgetprec(); \ _xpfpa_fpu_oldprec = fpgetprec(); \
fpsetprec(FP_PD); \ fpsetprec(FP_PD); \
@ -298,6 +346,18 @@
# define XPFPA_DECLARE \ # define XPFPA_DECLARE \
unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw; unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
# define XPFPA_HAVE_CW 1
# define XPFPA_CW_DATATYPE \
unsigned int
# define XPFPA_STORE_CW(vptr) do { \
__asm__ __volatile__ ("fnstcw %0" : "=m" (*((unsigned int *)(vptr)))); \
} while (0)
# define XPFPA_RESTORE_CW(vptr) do { \
__asm__ __volatile__ ("fldcw %0" : : "m" (*((unsigned int *)(vptr)))); \
} while (0)
# define XPFPA_SWITCH_DOUBLE() do { \ # define XPFPA_SWITCH_DOUBLE() do { \
__asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \ __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
_xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x100) | 0x200; \ _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x100) | 0x200; \
@ -345,6 +405,10 @@
generated code will behave as planned. generated code will behave as planned.
*/ */
# define XPFPA_DECLARE /* NOP */ # define XPFPA_DECLARE /* NOP */
# define XPFPA_HAVE_CW 0
# define XPFPA_CW_DATATYPE unsigned int
# define XPFPA_STORE_CW(variable) /* NOP */
# define XPFPA_RESTORE_CW(variable) /* NOP */
# define XPFPA_SWITCH_DOUBLE() /* NOP */ # define XPFPA_SWITCH_DOUBLE() /* NOP */
# define XPFPA_SWITCH_SINGLE() /* NOP */ # define XPFPA_SWITCH_SINGLE() /* NOP */
# define XPFPA_SWITCH_DOUBLE_EXTENDED() /* NOP */ # define XPFPA_SWITCH_DOUBLE_EXTENDED() /* NOP */

View file

@ -254,6 +254,8 @@ struct _zend_executor_globals {
zend_bool active; zend_bool active;
void *saved_fpu_cw;
void *reserved[ZEND_MAX_RESERVED_RESOURCES]; void *reserved[ZEND_MAX_RESERVED_RESOURCES];
}; };

View file

@ -30,7 +30,6 @@
#include "zend_multiply.h" #include "zend_multiply.h"
#include "zend_strtod.h" #include "zend_strtod.h"
#include "zend_exceptions.h" #include "zend_exceptions.h"
#include "zend_float.h"
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1)) #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_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{ {
ZEND_FLOAT_DECLARE
zval op1_copy, op2_copy; zval op1_copy, op2_copy;
int converted = 0; 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) 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)) { && (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)); ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
ZEND_FLOAT_RESTORE();
} else { } else {
ZVAL_LONG(result, lval); 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): case TYPE_PAIR(IS_LONG, IS_DOUBLE):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2)); ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_LONG): case TYPE_PAIR(IS_DOUBLE, IS_LONG):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2))); ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_ARRAY, IS_ARRAY): { 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_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{ {
ZEND_FLOAT_DECLARE
zval op1_copy, op2_copy; zval op1_copy, op2_copy;
int converted = 0; 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) 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)) { && (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)); ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
ZEND_FLOAT_RESTORE();
} else { } else {
ZVAL_LONG(result, lval); 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): case TYPE_PAIR(IS_LONG, IS_DOUBLE):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2)); ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_LONG): case TYPE_PAIR(IS_DOUBLE, IS_LONG):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2))); ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
default: 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_API int mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{ {
ZEND_FLOAT_DECLARE
zval op1_copy, op2_copy; zval op1_copy, op2_copy;
int converted = 0; 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): { case TYPE_PAIR(IS_LONG, IS_LONG): {
long overflow; 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_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; Z_TYPE_P(result) = overflow ? IS_DOUBLE : IS_LONG;
return SUCCESS; return SUCCESS;
} }
case TYPE_PAIR(IS_LONG, IS_DOUBLE): case TYPE_PAIR(IS_LONG, IS_DOUBLE):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2)); ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_LONG): case TYPE_PAIR(IS_DOUBLE, IS_LONG):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2))); ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
default: 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_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{ {
ZEND_FLOAT_DECLARE
zval op1_copy, op2_copy; zval op1_copy, op2_copy;
int converted = 0; 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 */ return FAILURE; /* division by zero */
} else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) { } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN) {
/* Prevent overflow error/crash */ /* Prevent overflow error/crash */
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, (double) LONG_MIN / -1); ZVAL_DOUBLE(result, (double) LONG_MIN / -1);
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
} }
if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */ if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2)); ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
} else { } else {
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2)); ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
ZEND_FLOAT_RESTORE();
} }
return SUCCESS; return SUCCESS;
@ -951,9 +918,7 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
ZVAL_BOOL(result, 0); ZVAL_BOOL(result, 0);
return FAILURE; /* division by zero */ return FAILURE; /* division by zero */
} }
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2)); ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_LONG, IS_DOUBLE): 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); ZVAL_BOOL(result, 0);
return FAILURE; /* division by zero */ return FAILURE; /* division by zero */
} }
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2)); ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE): 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); ZVAL_BOOL(result, 0);
return FAILURE; /* division by zero */ return FAILURE; /* division by zero */
} }
ZEND_FLOAT_ENSURE();
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2)); ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
ZEND_FLOAT_RESTORE();
return SUCCESS; return SUCCESS;
default: default:

View file

@ -93,7 +93,6 @@
#include <zend_operators.h> #include <zend_operators.h>
#include <zend_strtod.h> #include <zend_strtod.h>
#include <zend_float.h>
#ifdef ZTS #ifdef ZTS
#include <TSRM.h> #include <TSRM.h>
@ -2033,7 +2032,6 @@ ret1:
ZEND_API double zend_strtod (CONST char *s00, char **se) ZEND_API double zend_strtod (CONST char *s00, char **se)
{ {
ZEND_FLOAT_DECLARE
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
CONST char *s, *s0, *s1; CONST char *s, *s0, *s1;
@ -2046,8 +2044,6 @@ ZEND_API double zend_strtod (CONST char *s00, char **se)
CONST char decimal_point = '.'; CONST char decimal_point = '.';
ZEND_FLOAT_ENSURE();
sign = nz0 = nz = 0; sign = nz0 = nz = 0;
value(rv) = 0.; value(rv) = 0.;
@ -2578,7 +2574,7 @@ ret:
} }
_THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult_mutex); _THREAD_PRIVATE_MUTEX_UNLOCK(pow5mult_mutex);
ZEND_FLOAT_RETURN(result); return result;
} }
ZEND_API double zend_hex_strtod(const char *str, char **endptr) ZEND_API double zend_hex_strtod(const char *str, char **endptr)

View file

@ -1452,7 +1452,7 @@ PHP_ADD_SOURCES(Zend, \
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \ zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \ zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
zend_closures.c) zend_closures.c zend_float.c)
if test -r "$abs_srcdir/Zend/zend_objects.c"; then if test -r "$abs_srcdir/Zend/zend_objects.c"; then
PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c) PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)

View file

@ -24,7 +24,6 @@
#include "php.h" #include "php.h"
#include "php_math.h" #include "php_math.h"
#include "zend_multiply.h" #include "zend_multiply.h"
#include "zend_float.h"
#include <math.h> #include <math.h>
#include <float.h> #include <float.h>
@ -94,10 +93,8 @@ static inline double php_intpow10(int power) {
/* {{{ php_round_helper /* {{{ php_round_helper
Actually performs the rounding of a value to integer in a certain mode */ Actually performs the rounding of a value to integer in a certain mode */
static inline double php_round_helper(double value, int mode) { static inline double php_round_helper(double value, int mode) {
ZEND_FLOAT_DECLARE
double tmp_value; double tmp_value;
ZEND_FLOAT_ENSURE();
if (value >= 0.0) { if (value >= 0.0) {
tmp_value = floor(value + 0.5); tmp_value = floor(value + 0.5);
if ((mode == PHP_ROUND_HALF_DOWN && value == (-0.5 + tmp_value)) || if ((mode == PHP_ROUND_HALF_DOWN && value == (-0.5 + tmp_value)) ||
@ -116,7 +113,7 @@ static inline double php_round_helper(double value, int mode) {
} }
} }
ZEND_FLOAT_RETURN(tmp_value); return tmp_value;
} }
/* }}} */ /* }}} */
@ -126,13 +123,10 @@ static inline double php_round_helper(double value, int mode) {
* mode. For the specifics of the algorithm, see http://wiki.php.net/rfc/rounding * mode. For the specifics of the algorithm, see http://wiki.php.net/rfc/rounding
*/ */
PHPAPI double _php_math_round(double value, int places, int mode) { PHPAPI double _php_math_round(double value, int places, int mode) {
ZEND_FLOAT_DECLARE
double f1, f2; double f1, f2;
double tmp_value; double tmp_value;
int precision_places; int precision_places;
ZEND_FLOAT_ENSURE();
precision_places = 14 - php_intlog10abs(value); precision_places = 14 - php_intlog10abs(value);
f1 = php_intpow10(abs(places)); f1 = php_intpow10(abs(places));
@ -163,7 +157,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
} }
/* This value is beyond our precision, so rounding it is pointless */ /* This value is beyond our precision, so rounding it is pointless */
if (fabs(tmp_value) >= 1e15) { if (fabs(tmp_value) >= 1e15) {
ZEND_FLOAT_RETURN(value); return value;
} }
} }
@ -196,7 +190,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
} }
} }
ZEND_FLOAT_RETURN(tmp_value); return tmp_value;
} }
/* }}} */ /* }}} */

View file

@ -311,7 +311,8 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
zend_sprintf.c zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c \ zend_sprintf.c zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c \
zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \ zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
zend_object_handlers.c zend_objects_API.c \ zend_object_handlers.c zend_objects_API.c \
zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c"); zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \
zend_float.c");
ADD_SOURCES("main", "main.c snprintf.c spprintf.c safe_mode.c getopt.c fopen_wrappers.c \ ADD_SOURCES("main", "main.c snprintf.c spprintf.c safe_mode.c getopt.c fopen_wrappers.c \
php_scandir.c php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ php_scandir.c php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \