Jacek Caban jacek@codeweavers.com writes:
+#include <math.h> +#include "basetsd.h"
+#ifndef NAN
+#ifdef __GNUC__
+# define NAN \
- (__extension__ \
- ((union { unsigned __l __attribute__ ((__mode__ (__SI__))); float __d; }) \
- { __l: 0x7fc00000UL }).__d)
+#else /* __GNUC__ */
+#ifdef WORDS_BIGENDIAN +# define __nan_bytes { 0x7f, 0xc0, 0, 0 } +#else +# define __nan_bytes { 0, 0, 0xc0, 0x7f } +#endif
+static union { unsigned char __c[4]; float __d; } __nan_union
- __attribute_used__ = { __nan_bytes };
+# define NAN (__nan_union.__d)
+#endif /* __GNUC__ */
+#endif /* NAN */
I'd suggest to take advantage of the variant union instead of copying all these glibc definitions. Something like
#ifdef NAN V_R8(&vt) = NAN; #else V_I8(&vt) = nan_magic_pattern; #endif
Alexandre Julliard wrote:
I'd suggest to take advantage of the variant union instead of copying all these glibc definitions. Something like
#ifdef NAN V_R8(&vt) = NAN; #else V_I8(&vt) = nan_magic_pattern; #endif
The problem is that nan_magic_pattern would have to be 8 bytes and AFAIK there is no portable way to do it without ugly casts like in attached patch.
Thanks, Jacek
From bae01a44932b20aa31cf3d9ca09f31a970ea1791 Mon Sep 17 00:00:00 2001
From: Jacek Caban jacek@codeweavers.com Date: Wed, 15 Oct 2008 16:45:09 -0500 Subject: [PATCH] jscript: Added NaN value implementation. To: wine-patches wine-patches@winehq.org
--- dlls/jscript/global.c | 15 +++++++++++++-- dlls/jscript/jscript.h | 16 ++++++++++++++++ dlls/jscript/jsutils.c | 3 +++ dlls/jscript/tests/lang.js | 3 +++ 4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/global.c b/dlls/jscript/global.c index a1c76de..e397c3d 100644 --- a/dlls/jscript/global.c +++ b/dlls/jscript/global.c @@ -108,8 +108,19 @@ static HRESULT constructor_call(DispatchEx *constr, LCID lcid, WORD flags, DISPP static HRESULT JSGlobal_NaN(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, VARIANT *retv, jsexcept_t *ei, IServiceProvider *sp) { - FIXME("\n"); - return E_NOTIMPL; + TRACE("\n"); + + switch(flags) { + case DISPATCH_PROPERTYGET: + num_set_nan(retv); + break; + + default: + FIXME("unimplemented flags %x\n", flags); + return E_NOTIMPL; + } + + return S_OK; }
static HRESULT JSGlobal_Infinity(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp, diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 691ac9e..4d4ad0f 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -242,6 +242,22 @@ static inline void num_set_val(VARIANT *v, DOUBLE d) } }
+static inline void num_set_nan(VARIANT *v) +{ + V_VT(v) = VT_R8; +#ifdef NAN + V_R8(v) = NAN; +#else +#ifdef WORDS_BIGENDIAN + ((DWORD*)&V_R8(v))[1] = 0x7ff80000; + ((DWORD*)&V_R8(v))[0] = 0; +#else + ((DWORD*)&V_R8(v))[0] = 0; + ((DWORD*)&V_R8(v))[1] = 0x7ff80000; +#endif +#endif +} + const char *debugstr_variant(const VARIANT*);
HRESULT WINAPI JScriptFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**); diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c index c6f4b9c..6507ce6 100644 --- a/dlls/jscript/jsutils.c +++ b/dlls/jscript/jsutils.c @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "config.h" +#include "wine/port.h" + #include <math.h>
#include "jscript.h" diff --git a/dlls/jscript/tests/lang.js b/dlls/jscript/tests/lang.js index b989645..5f14eb1 100644 --- a/dlls/jscript/tests/lang.js +++ b/dlls/jscript/tests/lang.js @@ -785,7 +785,10 @@ if (true) else ok(true, "else should be associated with nearest if statement");
+ok(isNaN(NaN) === true, "isNaN(NaN) !== true"); ok(isNaN(0.5) === false, "isNaN(0.5) !== false"); ok(isNaN() === true, "isNaN() !== true"); +ok(isNaN(NaN, 0) === true, "isNaN(NaN, 0) !== true"); +ok(isNaN(0.5, NaN) === false, "isNaN(0.5, NaN) !== false");
reportSuccess();
Jacek Caban jacek@codeweavers.com writes:
Alexandre Julliard wrote:
I'd suggest to take advantage of the variant union instead of copying all these glibc definitions. Something like
#ifdef NAN V_R8(&vt) = NAN; #else V_I8(&vt) = nan_magic_pattern; #endif
The problem is that nan_magic_pattern would have to be 8 bytes and AFAIK there is no portable way to do it without ugly casts like in attached patch.
Something like (ULONGLONG)0x7ff80000 << 32 should do the trick.
On Wed, Oct 15, 2008 at 04:50:30PM -0500, Jacek Caban wrote:
Alexandre Julliard wrote:
I'd suggest to take advantage of the variant union instead of copying all these glibc definitions. Something like
#ifdef NAN V_R8(&vt) = NAN; #else V_I8(&vt) = nan_magic_pattern; #endif
The problem is that nan_magic_pattern would have to be 8 bytes and AFAIK there is no portable way to do it without ugly casts like in attached patch.
And that break C's 'strict aliasing' rules that gcc might apply when optimising code.
David
2008/10/16 David Laight david@l8s.co.uk:
On Wed, Oct 15, 2008 at 04:50:30PM -0500, Jacek Caban wrote:
Alexandre Julliard wrote:
I'd suggest to take advantage of the variant union instead of copying all these glibc definitions. Something like
#ifdef NAN V_R8(&vt) = NAN; #else V_I8(&vt) = nan_magic_pattern; #endif
The problem is that nan_magic_pattern would have to be 8 bytes and AFAIK there is no portable way to do it without ugly casts like in attached patch.
And that break C's 'strict aliasing' rules that gcc might apply when optimising code.
Wine is compiled without strict aliasing already.