1/*
2 * Copyright (C) 2003, 2006 Apple Computer, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 * USA.
18 *
19 */
20
21#include <math.h>
22#include "global.h"
23
24namespace KJS {
25
26// This file exists because JavaScriptCore needs to define the NaN and Inf globals in a way
27// that does not use a static initializer so we don't have a framework initialization routine.
28
29// The trick is to define the NaN and Inf globals with a different type than the declaration.
30// This trick works because the mangled name of the globals does not include the type, although
31// I'm not sure that's guaranteed. There could be alignment issues with this, since arrays of
32// characters don't necessarily need the same alignment doubles do, but for now it seems to work.
33// It would be good to figure out a 100% clean way that still avoids code that runs at init time.
34
35#if (defined(AVOID_STATIC_CONSTRUCTORS) && !AVOID_STATIC_CONSTRUCTORS)
36 KJS_EXPORT extern const double NaN = NAN;
37 KJS_EXPORT extern const double Inf = INFINITY;
38#elif PLATFORM(DARWIN)
39
40#if PLATFORM(BIG_ENDIAN)
41 KJS_EXPORT extern const unsigned char NaN[sizeof(double)] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
42 KJS_EXPORT extern const unsigned char Inf[sizeof(double)] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
43#elif PLATFORM(MIDDLE_ENDIAN)
44 KJS_EXPORT extern const unsigned char NaN[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 };
45 KJS_EXPORT extern const unsigned char Inf[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 };
46#else
47 KJS_EXPORT extern const unsigned char NaN[sizeof(double)] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
48 KJS_EXPORT extern const unsigned char Inf[sizeof(double)] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
49#endif // PLATFORM(MIDDLE_ENDIAN)
50
51#else // !PLATFORM(DARWIN)
52
53// Note, we have to use union to ensure alignment. Otherwise, NaN_Bytes can start anywhere,
54// while NaN_double has to be 4-byte aligned for 32-bits.
55// With -fstrict-aliasing enabled, unions are the only safe way to do type masquerading.
56
57static const union {
58 struct {
59 unsigned char NaN_Bytes[8];
60 unsigned char Inf_Bytes[8];
61 } bytes;
62
63 struct {
64 double NaN_Double;
65 double Inf_Double;
66 } doubles;
67
68} NaNInf = { {
69#if PLATFORM(BIG_ENDIAN)
70 { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 },
71 { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
72#elif PLATFORM(MIDDLE_ENDIAN)
73 { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 },
74 { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }
75#else
76 { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f },
77 { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
78#endif
79} } ;
80
81 KJS_EXPORT extern const double NaN = NaNInf.doubles.NaN_Double;
82 KJS_EXPORT extern const double Inf = NaNInf.doubles.Inf_Double;
83
84#endif // !PLATFORM(DARWIN)
85
86
87} // namespace KJS
88