From 243dc2ff02e3be0af2a2f1aadf7e53f09b4bdbc7 Mon Sep 17 00:00:00 2001 From: "David N. Welton" Date: Mon, 15 Dec 2014 17:50:45 +0100 Subject: Fix one-letter typo --- lib/erl_interface/test/ei_encode_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/erl_interface/test/ei_encode_SUITE.erl b/lib/erl_interface/test/ei_encode_SUITE.erl index 50dc8b6a3c..86e0d8cd08 100644 --- a/lib/erl_interface/test/ei_encode_SUITE.erl +++ b/lib/erl_interface/test/ei_encode_SUITE.erl @@ -174,7 +174,7 @@ test_ei_encode_ulonglong(Config) when is_list(Config) -> %% ######################################################################## %% -%% A "character" for us is an 8 bit integer, alwasy positive, i.e. +%% A "character" for us is an 8 bit integer, always positive, i.e. %% it is unsigned. %% FIXME maybe the API should change to use "unsigned char" to be clear?! -- cgit v1.2.3 From 372d62d4e1738431d33c1318be1ee4305c74649d Mon Sep 17 00:00:00 2001 From: "David N. Welton" Date: Mon, 15 Dec 2014 17:53:09 +0100 Subject: Do not accept Nan and Infinity values Erlang does not accept these values, so we return an error in the C interface rather than letting them through to the Erlang VM, which rejects the message with a somewhat cryptic "bad external term". --- lib/erl_interface/configure.in | 12 ++++++++++++ lib/erl_interface/src/encode/encode_double.c | 12 ++++++++++++ lib/erl_interface/src/legacy/erl_eterm.c | 10 ++++++++++ 3 files changed, 34 insertions(+) diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in index ef78f0f87b..076170c648 100644 --- a/lib/erl_interface/configure.in +++ b/lib/erl_interface/configure.in @@ -139,6 +139,18 @@ esac AC_CHECK_LIB([nsl], [gethostbyname]) AC_CHECK_LIB([socket], [getpeername]) +AC_MSG_CHECKING([for isfinite]) +AC_TRY_LINK([#include ], + [isfinite(0);], have_isfinite=yes, have_isfinite=no), + +if test $have_isfinite = yes; then + AC_DEFINE(HAVE_ISFINITE,[1], + [Define to 1 if you have the `isfinite' function.]) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT diff --git a/lib/erl_interface/src/encode/encode_double.c b/lib/erl_interface/src/encode/encode_double.c index 148a49f73a..a19a871eda 100644 --- a/lib/erl_interface/src/encode/encode_double.c +++ b/lib/erl_interface/src/encode/encode_double.c @@ -18,6 +18,9 @@ */ #include #include +#if defined(HAVE_ISFINITE) +#include +#endif #include "eidef.h" #include "eiext.h" #include "putget.h" @@ -27,6 +30,15 @@ int ei_encode_double(char *buf, int *index, double p) char *s = buf + *index; char *s0 = s; + /* Erlang does not handle Inf and NaN, so we return an error rather + * than letting the Erlang VM complain about a bad external + * term. */ +#if defined(HAVE_ISFINITE) + if(!isfinite(p)) { + return -1; + } +#endif + if (!buf) s += 9; else { diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c index 636d26b24b..c167fd1f78 100644 --- a/lib/erl_interface/src/legacy/erl_eterm.c +++ b/lib/erl_interface/src/legacy/erl_eterm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "ei_locking.h" #include "ei_resolve.h" @@ -125,6 +126,15 @@ ETERM *erl_mk_float (double d) { ETERM *ep; + /* Erlang does not handle Inf and NaN, so we return an error + * rather than letting the Erlang VM complain about a bad external + * term. */ + switch(fpclassify(d)) { + case FP_NAN: + case FP_INFINITE: + return NULL; + } + ep = erl_alloc_eterm(ERL_FLOAT); ERL_COUNT(ep) = 1; ERL_FLOAT_VALUE(ep) = d; -- cgit v1.2.3 From 1c77269abc1a4772c8123470e93e1cd38f316e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Thu, 19 Mar 2015 11:38:42 +0100 Subject: erl_interface: Document non finite encoding returns --- lib/erl_interface/doc/src/ei.xml | 3 +++ lib/erl_interface/doc/src/erl_eterm.xml | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/erl_interface/doc/src/ei.xml b/lib/erl_interface/doc/src/ei.xml index 90495eebd6..32e0e0e2d8 100644 --- a/lib/erl_interface/doc/src/ei.xml +++ b/lib/erl_interface/doc/src/ei.xml @@ -202,6 +202,9 @@ typedef enum {

Encodes a double-precision (64 bit) floating point number in the binary format.

+

+ The function returns if the floating point number is not finite. +

diff --git a/lib/erl_interface/doc/src/erl_eterm.xml b/lib/erl_interface/doc/src/erl_eterm.xml index 429f77501c..2152192696 100644 --- a/lib/erl_interface/doc/src/erl_eterm.xml +++ b/lib/erl_interface/doc/src/erl_eterm.xml @@ -371,9 +371,11 @@ iohead ::= Binary

is a value to be converted to an Erlang float.

The function returns an Erlang float object with the value - specified in .

+ specified in or if + is not finite. +

can be used to retrieve the - value from an Erlang float.

+ value from an Erlang float.

-- cgit v1.2.3 From 5a5e2b781a544883f29b5c46fbbc38a198f70f23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 2 Jun 2015 14:39:30 +0200 Subject: erl_interface: Use isfinite instead of fpclassify --- lib/erl_interface/src/legacy/erl_eterm.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c index c167fd1f78..060e311f69 100644 --- a/lib/erl_interface/src/legacy/erl_eterm.c +++ b/lib/erl_interface/src/legacy/erl_eterm.c @@ -129,10 +129,8 @@ ETERM *erl_mk_float (double d) /* Erlang does not handle Inf and NaN, so we return an error * rather than letting the Erlang VM complain about a bad external * term. */ - switch(fpclassify(d)) { - case FP_NAN: - case FP_INFINITE: - return NULL; + if(!isfinite(d)) { + return NULL; } ep = erl_alloc_eterm(ERL_FLOAT); -- cgit v1.2.3 From 20dc34bfc200758f6a837d193e042d1e4653562f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 2 Jun 2015 14:55:39 +0200 Subject: erl_interface: Move isfinite definition to header --- lib/erl_interface/src/decode/decode_big.c | 21 --------------------- lib/erl_interface/src/misc/eidef.h | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/erl_interface/src/decode/decode_big.c b/lib/erl_interface/src/decode/decode_big.c index 477880b331..016ed2eac2 100644 --- a/lib/erl_interface/src/decode/decode_big.c +++ b/lib/erl_interface/src/decode/decode_big.c @@ -150,27 +150,6 @@ int ei_big_comp(erlang_big *x, erlang_big *y) #define INLINED_FP_CONVERSION 1 #endif -#ifdef USE_ISINF_ISNAN /* simulate finite() */ -# define isfinite(f) (!isinf(f) && !isnan(f)) -# define HAVE_ISFINITE -#elif defined(__GNUC__) && defined(HAVE_FINITE) -/* We use finite in gcc as it emits assembler instead of - the function call that isfinite emits. The assembler is - significantly faster. */ -# ifdef isfinite -# undef isfinite -# endif -# define isfinite finite -# ifndef HAVE_ISFINITE -# define HAVE_ISFINITE -# endif -#elif defined(isfinite) && !defined(HAVE_ISFINITE) -# define HAVE_ISFINITE -#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE) -# define isfinite finite -# define HAVE_ISFINITE -#endif - #ifdef NO_FPE_SIGNALS # define ERTS_FP_CHECK_INIT() do {} while (0) # define ERTS_FP_ERROR(f, Action) if (!isfinite(f)) { Action; } else {} diff --git a/lib/erl_interface/src/misc/eidef.h b/lib/erl_interface/src/misc/eidef.h index bd3d0bf631..e0dc325b48 100644 --- a/lib/erl_interface/src/misc/eidef.h +++ b/lib/erl_interface/src/misc/eidef.h @@ -41,6 +41,27 @@ typedef int socklen_t; #endif +#ifdef USE_ISINF_ISNAN /* simulate finite() */ +# define isfinite(f) (!isinf(f) && !isnan(f)) +# define HAVE_ISFINITE +#elif defined(__GNUC__) && defined(HAVE_FINITE) +/* We use finite in gcc as it emits assembler instead of + the function call that isfinite emits. The assembler is + significantly faster. */ +# ifdef isfinite +# undef isfinite +# endif +# define isfinite finite +# ifndef HAVE_ISFINITE +# define HAVE_ISFINITE +# endif +#elif defined(isfinite) && !defined(HAVE_ISFINITE) +# define HAVE_ISFINITE +#elif !defined(HAVE_ISFINITE) && defined(HAVE_FINITE) +# define isfinite finite +# define HAVE_ISFINITE +#endif + typedef unsigned char uint8; /* FIXME use configure */ typedef unsigned short uint16; typedef unsigned int uint32; -- cgit v1.2.3 From d1ec79afdeb91521ed55d8664c89f2afba792fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 2 Jun 2015 15:03:06 +0200 Subject: erl_interface: Surround isfinite with HAVE_ISFINITE conditional --- lib/erl_interface/src/legacy/erl_eterm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/erl_interface/src/legacy/erl_eterm.c b/lib/erl_interface/src/legacy/erl_eterm.c index 060e311f69..66cca7decf 100644 --- a/lib/erl_interface/src/legacy/erl_eterm.c +++ b/lib/erl_interface/src/legacy/erl_eterm.c @@ -26,7 +26,9 @@ #include #include #include +#if defined(HAVE_ISFINITE) #include +#endif #include "ei_locking.h" #include "ei_resolve.h" @@ -126,12 +128,14 @@ ETERM *erl_mk_float (double d) { ETERM *ep; +#if defined(HAVE_ISFINITE) /* Erlang does not handle Inf and NaN, so we return an error * rather than letting the Erlang VM complain about a bad external * term. */ if(!isfinite(d)) { return NULL; } +#endif ep = erl_alloc_eterm(ERL_FLOAT); ERL_COUNT(ep) = 1; -- cgit v1.2.3 From 49e7aba222d0eac504bb5018e98d201e70ea98ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 2 Jun 2015 15:04:10 +0200 Subject: erl_interface: Remove configure test for isfinite --- lib/erl_interface/configure.in | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in index 076170c648..ef78f0f87b 100644 --- a/lib/erl_interface/configure.in +++ b/lib/erl_interface/configure.in @@ -139,18 +139,6 @@ esac AC_CHECK_LIB([nsl], [gethostbyname]) AC_CHECK_LIB([socket], [getpeername]) -AC_MSG_CHECKING([for isfinite]) -AC_TRY_LINK([#include ], - [isfinite(0);], have_isfinite=yes, have_isfinite=no), - -if test $have_isfinite = yes; then - AC_DEFINE(HAVE_ISFINITE,[1], - [Define to 1 if you have the `isfinite' function.]) - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi - # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT -- cgit v1.2.3 From 1a2ae45a5999850c1578e9ea0c0f993c04f934fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 2 Jun 2015 15:12:03 +0200 Subject: erl_interface: Move math.h include after eidef.h --- lib/erl_interface/src/encode/encode_double.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/erl_interface/src/encode/encode_double.c b/lib/erl_interface/src/encode/encode_double.c index a19a871eda..72a1c60808 100644 --- a/lib/erl_interface/src/encode/encode_double.c +++ b/lib/erl_interface/src/encode/encode_double.c @@ -18,12 +18,12 @@ */ #include #include -#if defined(HAVE_ISFINITE) -#include -#endif #include "eidef.h" #include "eiext.h" #include "putget.h" +#if defined(HAVE_ISFINITE) +#include +#endif int ei_encode_double(char *buf, int *index, double p) { -- cgit v1.2.3