|
|
1.1 root 1: /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2: *
3: * The contents of this file are subject to the Netscape Public
4: * License Version 1.1 (the "License"); you may not use this file
5: * except in compliance with the License. You may obtain a copy of
6: * the License at http://www.mozilla.org/NPL/
7: *
8: * Software distributed under the License is distributed on an "AS
9: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10: * implied. See the License for the specific language governing
11: * rights and limitations under the License.
12: *
13: * The Original Code is Mozilla Communicator client code, released
14: * March 31, 1998.
15: *
16: * The Initial Developer of the Original Code is Netscape
17: * Communications Corporation. Portions created by Netscape are
18: * Copyright (C) 1998 Netscape Communications Corporation. All
19: * Rights Reserved.
20: *
21: * Contributor(s):
22: *
23: * Alternatively, the contents of this file may be used under the
24: * terms of the GNU Public License (the "GPL"), in which case the
25: * provisions of the GPL are applicable instead of those above.
26: * If you wish to allow use of your version of this file only
27: * under the terms of the GPL and not to allow others to use your
28: * version of this file under the NPL, indicate your decision by
29: * deleting the provisions above and replace them with the notice
30: * and other provisions required by the GPL. If you do not delete
31: * the provisions above, a recipient may use your version of this
32: * file under either the NPL or the GPL.
33: */
34:
35: #ifndef jsnum_h___
36: #define jsnum_h___
37: /*
38: * JS number (IEEE double) interface.
39: *
40: * JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
41: * but floating point literals, results that overflow 31 bits, and division and
42: * modulus operands and results require a 64-bit IEEE double. These are GC'ed
43: * and pointed to by 32-bit jsvals on the stack and in object properties.
44: *
45: * When a JS number is treated as an object (followed by . or []), the runtime
46: * wraps it with a JSObject whose valueOf method returns the unwrapped number.
47: */
48:
49: JS_BEGIN_EXTERN_C
50:
51: /*
52: * Stefan Hanske <[email protected]> reports:
53: * ARM is a little endian architecture but 64 bit double words are stored
54: * differently: the 32 bit words are in little endian byte order, the two words
55: * are stored in big endian`s way.
56: */
57:
58: #if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__)
59: #define CPU_IS_ARM
60: #endif
61:
62: typedef union jsdpun {
63: struct {
64: #if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
65: uint32 lo, hi;
66: #else
67: uint32 hi, lo;
68: #endif
69: } s;
70: jsdouble d;
71: } jsdpun;
72:
73: #if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2
74: /*
75: * This version of the macros is safe for the alias optimizations that gcc
76: * does, but uses gcc-specific extensions.
77: */
78:
79: #define JSDOUBLE_HI32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.hi; }))
80: #define JSDOUBLE_LO32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.lo; }))
81: #define JSDOUBLE_SET_HI32(x, y) \
82: (__extension__ ({ jsdpun u; u.d = (x); u.s.hi = (y); (x) = u.d; }))
83: #define JSDOUBLE_SET_LO32(x, y) \
84: (__extension__ ({ jsdpun u; u.d = (x); u.s.lo = (y); (x) = u.d; }))
85:
86: #else /* not or old GNUC */
87:
88: /*
89: * We don't know of any non-gcc compilers that perform alias optimization,
90: * so this code should work.
91: */
92:
93: #if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM)
94: #define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1])
95: #define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0])
96: #else
97: #define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0])
98: #define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1])
99: #endif
100:
101: #define JSDOUBLE_SET_HI32(x, y) (JSDOUBLE_HI32(x)=(y))
102: #define JSDOUBLE_SET_LO32(x, y) (JSDOUBLE_LO32(x)=(y))
103:
104: #endif /* not or old GNUC */
105:
106: #define JSDOUBLE_HI32_SIGNBIT 0x80000000
107: #define JSDOUBLE_HI32_EXPMASK 0x7ff00000
108: #define JSDOUBLE_HI32_MANTMASK 0x000fffff
109:
110: #define JSDOUBLE_IS_NaN(x) \
111: ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \
112: (JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
113:
114: #define JSDOUBLE_IS_INFINITE(x) \
115: ((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \
116: !JSDOUBLE_LO32(x))
117:
118: #define JSDOUBLE_IS_FINITE(x) \
119: ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)
120:
121: #define JSDOUBLE_IS_NEGZERO(d) (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
122: JSDOUBLE_LO32(d) == 0)
123:
124: /*
125: * JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid
126: * raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is
127: * safe) leaves i as (jsint)d. This also avoid anomalous NaN floating point
128: * comparisons under MSVC.
129: */
130: #define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d) \
131: && !JSDOUBLE_IS_NEGZERO(d) \
132: && ((d) == (i = (jsint)(d))))
133:
134: /* Initialize number constants and runtime state for the first context. */
135: extern JSBool
136: js_InitRuntimeNumberState(JSContext *cx);
137:
138: extern void
139: js_FinishRuntimeNumberState(JSContext *cx);
140:
141: /* Initialize the Number class, returning its prototype object. */
142: extern JSObject *
143: js_InitNumberClass(JSContext *cx, JSObject *obj);
144:
145: /*
146: * String constants for global function names, used in jsapi.c and jsnum.c.
147: */
148: extern const char js_Infinity_str[];
149: extern const char js_NaN_str[];
150: extern const char js_isNaN_str[];
151: extern const char js_isFinite_str[];
152: extern const char js_parseFloat_str[];
153: extern const char js_parseInt_str[];
154:
155: /* GC-allocate a new JS number. */
156: extern jsdouble *
157: js_NewDouble(JSContext *cx, jsdouble d);
158:
159: extern void
160: js_FinalizeDouble(JSContext *cx, jsdouble *dp);
161:
162: extern JSBool
163: js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
164:
165: extern JSBool
166: js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
167:
168: /* Construct a Number instance that wraps around d. */
169: extern JSObject *
170: js_NumberToObject(JSContext *cx, jsdouble d);
171:
172: /* Convert a number to a GC'ed string. */
173: extern JSString *
174: js_NumberToString(JSContext *cx, jsdouble d);
175:
176: /*
177: * Convert a value to a number, returning false after reporting any error,
178: * otherwise returning true with *dp set.
179: */
180: extern JSBool
181: js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
182:
183: /*
184: * Convert a value or a double to an int32, according to the ECMA rules
185: * for ToInt32.
186: */
187: extern JSBool
188: js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip);
189:
190: extern JSBool
191: js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip);
192:
193: /*
194: * Convert a value or a double to a uint32, according to the ECMA rules
195: * for ToUint32.
196: */
197: extern JSBool
198: js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip);
199:
200: extern JSBool
201: js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip);
202:
203: /*
204: * Convert a value to a number, then to an int32 if it fits by rounding to
205: * nearest; but failing with an error report if the double is out of range
206: * or unordered.
207: */
208: extern JSBool
209: js_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
210:
211: /*
212: * Convert a value to a number, then to a uint16 according to the ECMA rules
213: * for ToUint16.
214: */
215: extern JSBool
216: js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
217:
218: /*
219: * Convert a jsdouble to an integral number, stored in a jsdouble.
220: * If d is NaN, return 0. If d is an infinity, return it without conversion.
221: */
222: extern jsdouble
223: js_DoubleToInteger(jsdouble d);
224:
225: /*
226: * Similar to strtod except that it replaces overflows with infinities of the
227: * correct sign, and underflows with zeros of the correct sign. Guaranteed to
228: * return the closest double number to the given input in dp.
229: *
230: * Also allows inputs of the form [+|-]Infinity, which produce an infinity of
231: * the appropriate sign. The case of the "Infinity" string must match exactly.
232: * If the string does not contain a number, set *ep to s and return 0.0 in dp.
233: * Return false if out of memory.
234: */
235: extern JSBool
236: js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp);
237:
238: /*
239: * Similar to strtol except that it handles integers of arbitrary size.
240: * Guaranteed to return the closest double number to the given input when radix
241: * is 10 or a power of 2. Callers may see round-off errors for very large
242: * numbers of a different radix than 10 or a power of 2.
243: *
244: * If the string does not contain a number, set *ep to s and return 0.0 in dp.
245: * Return false if out of memory.
246: */
247: extern JSBool
248: js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint radix, jsdouble *dp);
249:
250: JS_END_EXTERN_C
251:
252: #endif /* jsnum_h___ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.