|
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/. */ |
|
6 |
|
7 #ifndef jsmath_h |
|
8 #define jsmath_h |
|
9 |
|
10 #include "mozilla/MemoryReporting.h" |
|
11 |
|
12 #include "NamespaceImports.h" |
|
13 |
|
14 #ifndef M_PI |
|
15 # define M_PI 3.14159265358979323846 |
|
16 #endif |
|
17 #ifndef M_E |
|
18 # define M_E 2.7182818284590452354 |
|
19 #endif |
|
20 #ifndef M_LOG2E |
|
21 # define M_LOG2E 1.4426950408889634074 |
|
22 #endif |
|
23 #ifndef M_LOG10E |
|
24 # define M_LOG10E 0.43429448190325182765 |
|
25 #endif |
|
26 #ifndef M_LN2 |
|
27 # define M_LN2 0.69314718055994530942 |
|
28 #endif |
|
29 #ifndef M_LN10 |
|
30 # define M_LN10 2.30258509299404568402 |
|
31 #endif |
|
32 #ifndef M_SQRT2 |
|
33 # define M_SQRT2 1.41421356237309504880 |
|
34 #endif |
|
35 #ifndef M_SQRT1_2 |
|
36 # define M_SQRT1_2 0.70710678118654752440 |
|
37 #endif |
|
38 |
|
39 namespace js { |
|
40 |
|
41 typedef double (*UnaryFunType)(double); |
|
42 |
|
43 class MathCache |
|
44 { |
|
45 static const unsigned SizeLog2 = 12; |
|
46 static const unsigned Size = 1 << SizeLog2; |
|
47 struct Entry { double in; UnaryFunType f; double out; }; |
|
48 Entry table[Size]; |
|
49 |
|
50 public: |
|
51 MathCache(); |
|
52 |
|
53 unsigned hash(double x) { |
|
54 union { double d; struct { uint32_t one, two; } s; } u = { x }; |
|
55 uint32_t hash32 = u.s.one ^ u.s.two; |
|
56 uint16_t hash16 = uint16_t(hash32 ^ (hash32 >> 16)); |
|
57 return (hash16 & (Size - 1)) ^ (hash16 >> (16 - SizeLog2)); |
|
58 } |
|
59 |
|
60 /* |
|
61 * N.B. lookup uses double-equality. This is only safe if hash() maps +0 |
|
62 * and -0 to different table entries, which is asserted in MathCache(). |
|
63 */ |
|
64 double lookup(UnaryFunType f, double x) { |
|
65 unsigned index = hash(x); |
|
66 Entry &e = table[index]; |
|
67 if (e.in == x && e.f == f) |
|
68 return e.out; |
|
69 e.in = x; |
|
70 e.f = f; |
|
71 return e.out = f(x); |
|
72 } |
|
73 |
|
74 size_t sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf); |
|
75 }; |
|
76 |
|
77 } /* namespace js */ |
|
78 |
|
79 /* |
|
80 * JS math functions. |
|
81 */ |
|
82 |
|
83 extern JSObject * |
|
84 js_InitMathClass(JSContext *cx, js::HandleObject obj); |
|
85 |
|
86 extern double |
|
87 math_random_no_outparam(JSContext *cx); |
|
88 |
|
89 extern bool |
|
90 js_math_random(JSContext *cx, unsigned argc, js::Value *vp); |
|
91 |
|
92 extern bool |
|
93 js_math_abs(JSContext *cx, unsigned argc, js::Value *vp); |
|
94 |
|
95 extern bool |
|
96 js_math_max(JSContext *cx, unsigned argc, js::Value *vp); |
|
97 |
|
98 extern bool |
|
99 js_math_min(JSContext *cx, unsigned argc, js::Value *vp); |
|
100 |
|
101 extern bool |
|
102 js_math_sqrt(JSContext *cx, unsigned argc, js::Value *vp); |
|
103 |
|
104 extern bool |
|
105 js_math_pow(JSContext *cx, unsigned argc, js::Value *vp); |
|
106 |
|
107 namespace js { |
|
108 |
|
109 extern bool |
|
110 math_imul(JSContext *cx, unsigned argc, js::Value *vp); |
|
111 |
|
112 extern bool |
|
113 RoundFloat32(JSContext *cx, Handle<Value> v, float *out); |
|
114 |
|
115 extern bool |
|
116 math_fround(JSContext *cx, unsigned argc, js::Value *vp); |
|
117 |
|
118 extern bool |
|
119 math_log(JSContext *cx, unsigned argc, js::Value *vp); |
|
120 |
|
121 extern double |
|
122 math_log_impl(MathCache *cache, double x); |
|
123 |
|
124 extern double |
|
125 math_log_uncached(double x); |
|
126 |
|
127 extern bool |
|
128 math_sin(JSContext *cx, unsigned argc, js::Value *vp); |
|
129 |
|
130 extern double |
|
131 math_sin_impl(MathCache *cache, double x); |
|
132 |
|
133 extern double |
|
134 math_sin_uncached(double x); |
|
135 |
|
136 extern bool |
|
137 math_cos(JSContext *cx, unsigned argc, js::Value *vp); |
|
138 |
|
139 extern double |
|
140 math_cos_impl(MathCache *cache, double x); |
|
141 |
|
142 extern double |
|
143 math_cos_uncached(double x); |
|
144 |
|
145 extern bool |
|
146 math_exp(JSContext *cx, unsigned argc, js::Value *vp); |
|
147 |
|
148 extern double |
|
149 math_exp_impl(MathCache *cache, double x); |
|
150 |
|
151 extern double |
|
152 math_exp_uncached(double x); |
|
153 |
|
154 extern bool |
|
155 math_tan(JSContext *cx, unsigned argc, js::Value *vp); |
|
156 |
|
157 extern double |
|
158 math_tan_impl(MathCache *cache, double x); |
|
159 |
|
160 extern double |
|
161 math_tan_uncached(double x); |
|
162 |
|
163 extern bool |
|
164 math_log10(JSContext *cx, unsigned argc, js::Value *vp); |
|
165 |
|
166 extern bool |
|
167 math_log2(JSContext *cx, unsigned argc, js::Value *vp); |
|
168 |
|
169 extern bool |
|
170 math_log1p(JSContext *cx, unsigned argc, js::Value *vp); |
|
171 |
|
172 extern bool |
|
173 math_expm1(JSContext *cx, unsigned argc, js::Value *vp); |
|
174 |
|
175 extern bool |
|
176 math_cosh(JSContext *cx, unsigned argc, js::Value *vp); |
|
177 |
|
178 extern bool |
|
179 math_sinh(JSContext *cx, unsigned argc, js::Value *vp); |
|
180 |
|
181 extern bool |
|
182 math_tanh(JSContext *cx, unsigned argc, js::Value *vp); |
|
183 |
|
184 extern bool |
|
185 math_acosh(JSContext *cx, unsigned argc, js::Value *vp); |
|
186 |
|
187 extern bool |
|
188 math_asinh(JSContext *cx, unsigned argc, js::Value *vp); |
|
189 |
|
190 extern bool |
|
191 math_atanh(JSContext *cx, unsigned argc, js::Value *vp); |
|
192 |
|
193 extern double |
|
194 ecmaHypot(double x, double y); |
|
195 |
|
196 extern bool |
|
197 math_hypot(JSContext *cx, unsigned argc, Value *vp); |
|
198 |
|
199 extern bool |
|
200 math_trunc(JSContext *cx, unsigned argc, Value *vp); |
|
201 |
|
202 extern bool |
|
203 math_sign(JSContext *cx, unsigned argc, Value *vp); |
|
204 |
|
205 extern bool |
|
206 math_cbrt(JSContext *cx, unsigned argc, Value *vp); |
|
207 |
|
208 extern bool |
|
209 math_asin(JSContext *cx, unsigned argc, Value *vp); |
|
210 |
|
211 extern bool |
|
212 math_acos(JSContext *cx, unsigned argc, Value *vp); |
|
213 |
|
214 extern bool |
|
215 math_atan(JSContext *cx, unsigned argc, Value *vp); |
|
216 |
|
217 extern bool |
|
218 math_atan2(JSContext *cx, unsigned argc, Value *vp); |
|
219 |
|
220 extern double |
|
221 ecmaAtan2(double x, double y); |
|
222 |
|
223 extern double |
|
224 math_atan_impl(MathCache *cache, double x); |
|
225 |
|
226 extern double |
|
227 math_atan_uncached(double x); |
|
228 |
|
229 extern bool |
|
230 math_atan(JSContext *cx, unsigned argc, js::Value *vp); |
|
231 |
|
232 extern double |
|
233 math_asin_impl(MathCache *cache, double x); |
|
234 |
|
235 extern double |
|
236 math_asin_uncached(double x); |
|
237 |
|
238 extern bool |
|
239 math_asin(JSContext *cx, unsigned argc, js::Value *vp); |
|
240 |
|
241 extern double |
|
242 math_acos_impl(MathCache *cache, double x); |
|
243 |
|
244 extern double |
|
245 math_acos_uncached(double x); |
|
246 |
|
247 extern bool |
|
248 math_acos(JSContext *cx, unsigned argc, js::Value *vp); |
|
249 |
|
250 extern bool |
|
251 math_ceil(JSContext *cx, unsigned argc, Value *vp); |
|
252 |
|
253 extern double |
|
254 math_ceil_impl(double x); |
|
255 |
|
256 extern bool |
|
257 math_clz32(JSContext *cx, unsigned argc, Value *vp); |
|
258 |
|
259 extern bool |
|
260 math_floor(JSContext *cx, unsigned argc, Value *vp); |
|
261 |
|
262 extern double |
|
263 math_floor_impl(double x); |
|
264 |
|
265 extern bool |
|
266 math_round(JSContext *cx, unsigned argc, Value *vp); |
|
267 |
|
268 extern double |
|
269 math_round_impl(double x); |
|
270 |
|
271 extern float |
|
272 math_roundf_impl(float x); |
|
273 |
|
274 extern double |
|
275 powi(double x, int y); |
|
276 |
|
277 extern double |
|
278 ecmaPow(double x, double y); |
|
279 |
|
280 extern bool |
|
281 math_imul(JSContext *cx, unsigned argc, Value *vp); |
|
282 |
|
283 extern double |
|
284 math_log10_impl(MathCache *cache, double x); |
|
285 |
|
286 extern double |
|
287 math_log10_uncached(double x); |
|
288 |
|
289 extern double |
|
290 math_log2_impl(MathCache *cache, double x); |
|
291 |
|
292 extern double |
|
293 math_log2_uncached(double x); |
|
294 |
|
295 extern double |
|
296 math_log1p_impl(MathCache *cache, double x); |
|
297 |
|
298 extern double |
|
299 math_log1p_uncached(double x); |
|
300 |
|
301 extern double |
|
302 math_expm1_impl(MathCache *cache, double x); |
|
303 |
|
304 extern double |
|
305 math_expm1_uncached(double x); |
|
306 |
|
307 extern double |
|
308 math_cosh_impl(MathCache *cache, double x); |
|
309 |
|
310 extern double |
|
311 math_cosh_uncached(double x); |
|
312 |
|
313 extern double |
|
314 math_sinh_impl(MathCache *cache, double x); |
|
315 |
|
316 extern double |
|
317 math_sinh_uncached(double x); |
|
318 |
|
319 extern double |
|
320 math_tanh_impl(MathCache *cache, double x); |
|
321 |
|
322 extern double |
|
323 math_tanh_uncached(double x); |
|
324 |
|
325 extern double |
|
326 math_acosh_impl(MathCache *cache, double x); |
|
327 |
|
328 extern double |
|
329 math_acosh_uncached(double x); |
|
330 |
|
331 extern double |
|
332 math_asinh_impl(MathCache *cache, double x); |
|
333 |
|
334 extern double |
|
335 math_asinh_uncached(double x); |
|
336 |
|
337 extern double |
|
338 math_atanh_impl(MathCache *cache, double x); |
|
339 |
|
340 extern double |
|
341 math_atanh_uncached(double x); |
|
342 |
|
343 extern double |
|
344 math_trunc_impl(MathCache *cache, double x); |
|
345 |
|
346 extern double |
|
347 math_trunc_uncached(double x); |
|
348 |
|
349 extern double |
|
350 math_sign_impl(MathCache *cache, double x); |
|
351 |
|
352 extern double |
|
353 math_sign_uncached(double x); |
|
354 |
|
355 extern double |
|
356 math_cbrt_impl(MathCache *cache, double x); |
|
357 |
|
358 extern double |
|
359 math_cbrt_uncached(double x); |
|
360 |
|
361 } /* namespace js */ |
|
362 |
|
363 #endif /* jsmath_h */ |