Bumping manifests a=b2g-bump
[gecko.git] / js / src / jsnum.h
blob1d908460268a8c10f2e122dc46ca391d76fdfb5d
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef jsnum_h
8 #define jsnum_h
10 #include "mozilla/FloatingPoint.h"
11 #include "mozilla/Range.h"
13 #include "NamespaceImports.h"
15 #include "js/Conversions.h"
17 namespace js {
19 class StringBuffer;
21 extern bool
22 InitRuntimeNumberState(JSRuntime* rt);
24 #if !EXPOSE_INTL_API
25 extern void
26 FinishRuntimeNumberState(JSRuntime* rt);
27 #endif
29 } /* namespace js */
31 /* Initialize the Number class, returning its prototype object. */
32 extern JSObject*
33 js_InitNumberClass(JSContext* cx, js::HandleObject obj);
36 * String constants for global function names, used in jsapi.c and jsnum.c.
38 extern const char js_isNaN_str[];
39 extern const char js_isFinite_str[];
40 extern const char js_parseFloat_str[];
41 extern const char js_parseInt_str[];
43 class JSAtom;
45 namespace js {
48 * When base == 10, this function implements ToString() as specified by
49 * ECMA-262-5 section 9.8.1; but note that it handles integers specially for
50 * performance. See also js::NumberToCString().
52 template <AllowGC allowGC>
53 extern JSString*
54 NumberToString(ExclusiveContext* cx, double d);
56 extern JSAtom*
57 NumberToAtom(ExclusiveContext* cx, double d);
59 template <AllowGC allowGC>
60 extern JSFlatString*
61 Int32ToString(ExclusiveContext* cx, int32_t i);
63 extern JSAtom*
64 Int32ToAtom(ExclusiveContext* cx, int32_t si);
67 * Convert an integer or double (contained in the given value) to a string and
68 * append to the given buffer.
70 extern bool JS_FASTCALL
71 NumberValueToStringBuffer(JSContext* cx, const Value& v, StringBuffer& sb);
73 /* Same as js_NumberToString, different signature. */
74 extern JSFlatString*
75 NumberToString(JSContext* cx, double d);
77 extern JSFlatString*
78 IndexToString(JSContext* cx, uint32_t index);
81 * Usually a small amount of static storage is enough, but sometimes we need
82 * to dynamically allocate much more. This struct encapsulates that.
83 * Dynamically allocated memory will be freed when the object is destroyed.
85 struct ToCStringBuf
88 * The longest possible result that would need to fit in sbuf is
89 * (-0x80000000).toString(2), which has length 33. Longer cases are
90 * possible, but they'll go in dbuf.
92 static const size_t sbufSize = 34;
93 char sbuf[sbufSize];
94 char* dbuf;
96 ToCStringBuf();
97 ~ToCStringBuf();
101 * Convert a number to a C string. When base==10, this function implements
102 * ToString() as specified by ECMA-262-5 section 9.8.1. It handles integral
103 * values cheaply. Return nullptr if we ran out of memory. See also
104 * js_NumberToCString().
106 extern char*
107 NumberToCString(JSContext* cx, ToCStringBuf* cbuf, double d, int base = 10);
110 * The largest positive integer such that all positive integers less than it
111 * may be precisely represented using the IEEE-754 double-precision format.
113 const double DOUBLE_INTEGRAL_PRECISION_LIMIT = uint64_t(1) << 53;
116 * Parse a decimal number encoded in |chars|. The decimal number must be
117 * sufficiently small that it will not overflow the integrally-precise range of
118 * the double type -- that is, the number will be smaller than
119 * DOUBLE_INTEGRAL_PRECISION_LIMIT
121 template <typename CharT>
122 extern double
123 ParseDecimalNumber(const mozilla::Range<const CharT> chars);
126 * Compute the positive integer of the given base described immediately at the
127 * start of the range [start, end) -- no whitespace-skipping, no magical
128 * leading-"0" octal or leading-"0x" hex behavior, no "+"/"-" parsing, just
129 * reading the digits of the integer. Return the index one past the end of the
130 * digits of the integer in *endp, and return the integer itself in *dp. If
131 * base is 10 or a power of two the returned integer is the closest possible
132 * double; otherwise extremely large integers may be slightly inaccurate.
134 * If [start, end) does not begin with a number with the specified base,
135 * *dp == 0 and *endp == start upon return.
137 template <typename CharT>
138 extern bool
139 GetPrefixInteger(ExclusiveContext* cx, const CharT* start, const CharT* end, int base,
140 const CharT** endp, double* dp);
143 * This is like GetPrefixInteger, but only deals with base 10, and doesn't have
144 * and |endp| outparam. It should only be used when the characters are known to
145 * only contain digits.
147 extern bool
148 GetDecimalInteger(ExclusiveContext* cx, const char16_t* start, const char16_t* end, double* dp);
150 extern bool
151 StringToNumber(ExclusiveContext* cx, JSString* str, double* result);
153 /* ES5 9.3 ToNumber, overwriting *vp with the appropriate number value. */
154 MOZ_ALWAYS_INLINE bool
155 ToNumber(JSContext* cx, JS::MutableHandleValue vp)
157 if (vp.isNumber())
158 return true;
159 double d;
160 extern JS_PUBLIC_API(bool) ToNumberSlow(JSContext* cx, Value v, double* dp);
161 if (!ToNumberSlow(cx, vp, &d))
162 return false;
164 vp.setNumber(d);
165 return true;
168 bool
169 num_parseInt(JSContext* cx, unsigned argc, Value* vp);
171 } /* namespace js */
174 * Similar to strtod except that it replaces overflows with infinities of the
175 * correct sign, and underflows with zeros of the correct sign. Guaranteed to
176 * return the closest double number to the given input in dp.
178 * Also allows inputs of the form [+|-]Infinity, which produce an infinity of
179 * the appropriate sign. The case of the "Infinity" string must match exactly.
180 * If the string does not contain a number, set *dEnd to begin and return 0.0
181 * in *d.
183 * Return false if out of memory.
185 template <typename CharT>
186 extern bool
187 js_strtod(js::ExclusiveContext* cx, const CharT* begin, const CharT* end,
188 const CharT** dEnd, double* d);
190 extern bool
191 js_num_toString(JSContext* cx, unsigned argc, js::Value* vp);
193 extern bool
194 js_num_valueOf(JSContext* cx, unsigned argc, js::Value* vp);
196 namespace js {
198 static MOZ_ALWAYS_INLINE bool
199 ValueFitsInInt32(const Value& v, int32_t* pi)
201 if (v.isInt32()) {
202 *pi = v.toInt32();
203 return true;
205 return v.isDouble() && mozilla::NumberIsInt32(v.toDouble(), pi);
209 * Returns true if the given value is definitely an index: that is, the value
210 * is a number that's an unsigned 32-bit integer.
212 * This method prioritizes common-case speed over accuracy in every case. It
213 * can produce false negatives (but not false positives): some values which are
214 * indexes will be reported not to be indexes by this method. Users must
215 * consider this possibility when using this method.
217 static MOZ_ALWAYS_INLINE bool
218 IsDefinitelyIndex(const Value& v, uint32_t* indexp)
220 if (v.isInt32() && v.toInt32() >= 0) {
221 *indexp = v.toInt32();
222 return true;
225 int32_t i;
226 if (v.isDouble() && mozilla::NumberIsInt32(v.toDouble(), &i) && i >= 0) {
227 *indexp = uint32_t(i);
228 return true;
231 return false;
234 /* ES5 9.4 ToInteger. */
235 static inline bool
236 ToInteger(JSContext* cx, HandleValue v, double* dp)
238 if (v.isInt32()) {
239 *dp = v.toInt32();
240 return true;
242 if (v.isDouble()) {
243 *dp = v.toDouble();
244 } else {
245 extern JS_PUBLIC_API(bool) ToNumberSlow(JSContext* cx, Value v, double* dp);
246 if (!ToNumberSlow(cx, v, dp))
247 return false;
249 *dp = JS::ToInteger(*dp);
250 return true;
253 /* ES6 7.1.15 ToLength, but clamped to the [0,2^32-2] range. If the
254 * return value is false then *overflow will be true iff the value was
255 * not clampable to uint32_t range.
257 * For JSContext and ExclusiveContext.
259 template<typename T>
260 bool ToLengthClamped(T* cx, HandleValue v, uint32_t* out, bool* overflow);
262 inline bool
263 SafeAdd(int32_t one, int32_t two, int32_t* res)
265 // Use unsigned for the 32-bit operation since signed overflow gets
266 // undefined behavior.
267 *res = uint32_t(one) + uint32_t(two);
268 int64_t ores = (int64_t)one + (int64_t)two;
269 return ores == (int64_t)*res;
272 inline bool
273 SafeSub(int32_t one, int32_t two, int32_t* res)
275 *res = uint32_t(one) - uint32_t(two);
276 int64_t ores = (int64_t)one - (int64_t)two;
277 return ores == (int64_t)*res;
280 inline bool
281 SafeMul(int32_t one, int32_t two, int32_t* res)
283 *res = uint32_t(one) * uint32_t(two);
284 int64_t ores = (int64_t)one * (int64_t)two;
285 return ores == (int64_t)*res;
288 extern bool
289 ToNumberSlow(ExclusiveContext* cx, Value v, double* dp);
291 // Variant of ToNumber which takes an ExclusiveContext instead of a JSContext.
292 // ToNumber is part of the API and can't use ExclusiveContext directly.
293 MOZ_ALWAYS_INLINE bool
294 ToNumber(ExclusiveContext* cx, const Value& v, double* out)
296 if (v.isNumber()) {
297 *out = v.toNumber();
298 return true;
300 return ToNumberSlow(cx, v, out);
303 void FIX_FPU();
305 } /* namespace js */
307 #endif /* jsnum_h */