/[jscoverage]/trunk/js/jsmath.cpp
ViewVC logotype

Annotation of /trunk/js/jsmath.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 399 - (hide annotations)
Tue Dec 9 03:37:47 2008 UTC (10 years, 10 months ago) by siliconforks
File size: 18841 byte(s)
Use SpiderMonkey from Firefox 3.1b2.

1 siliconforks 332 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2     *
3     * ***** BEGIN LICENSE BLOCK *****
4     * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5     *
6     * The contents of this file are subject to the Mozilla Public License Version
7     * 1.1 (the "License"); you may not use this file except in compliance with
8     * the License. You may obtain a copy of the License at
9     * http://www.mozilla.org/MPL/
10     *
11     * Software distributed under the License is distributed on an "AS IS" basis,
12     * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13     * for the specific language governing rights and limitations under the
14     * License.
15     *
16     * The Original Code is Mozilla Communicator client code, released
17     * March 31, 1998.
18     *
19     * The Initial Developer of the Original Code is
20     * Netscape Communications Corporation.
21     * Portions created by the Initial Developer are Copyright (C) 1998
22     * the Initial Developer. All Rights Reserved.
23     *
24     * Contributor(s):
25     *
26     * Alternatively, the contents of this file may be used under the terms of
27     * either of the GNU General Public License Version 2 or later (the "GPL"),
28     * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29     * in which case the provisions of the GPL or the LGPL are applicable instead
30     * of those above. If you wish to allow use of your version of this file only
31     * under the terms of either the GPL or the LGPL, and not to allow others to
32     * use your version of this file under the terms of the MPL, indicate your
33     * decision by deleting the provisions above and replace them with the notice
34     * and other provisions required by the GPL or the LGPL. If you do not delete
35     * the provisions above, a recipient may use your version of this file under
36     * the terms of any one of the MPL, the GPL or the LGPL.
37     *
38     * ***** END LICENSE BLOCK ***** */
39    
40     /*
41     * JS math package.
42     */
43     #include "jsstddef.h"
44     #include "jslibmath.h"
45     #include <stdlib.h>
46     #include "jstypes.h"
47     #include "jslong.h"
48     #include "prmjtime.h"
49     #include "jsapi.h"
50     #include "jsatom.h"
51 siliconforks 399 #include "jsbuiltins.h"
52 siliconforks 332 #include "jscntxt.h"
53     #include "jsversion.h"
54     #include "jslock.h"
55     #include "jsmath.h"
56     #include "jsnum.h"
57     #include "jsobj.h"
58    
59 siliconforks 399 extern jsdouble js_NaN;
60    
61 siliconforks 332 #ifndef M_E
62     #define M_E 2.7182818284590452354
63     #endif
64     #ifndef M_LOG2E
65     #define M_LOG2E 1.4426950408889634074
66     #endif
67     #ifndef M_LOG10E
68     #define M_LOG10E 0.43429448190325182765
69     #endif
70     #ifndef M_LN2
71     #define M_LN2 0.69314718055994530942
72     #endif
73     #ifndef M_LN10
74     #define M_LN10 2.30258509299404568402
75     #endif
76     #ifndef M_PI
77     #define M_PI 3.14159265358979323846
78     #endif
79     #ifndef M_SQRT2
80     #define M_SQRT2 1.41421356237309504880
81     #endif
82     #ifndef M_SQRT1_2
83     #define M_SQRT1_2 0.70710678118654752440
84     #endif
85    
86     static JSConstDoubleSpec math_constants[] = {
87     {M_E, "E", 0, {0,0,0}},
88     {M_LOG2E, "LOG2E", 0, {0,0,0}},
89     {M_LOG10E, "LOG10E", 0, {0,0,0}},
90     {M_LN2, "LN2", 0, {0,0,0}},
91     {M_LN10, "LN10", 0, {0,0,0}},
92     {M_PI, "PI", 0, {0,0,0}},
93     {M_SQRT2, "SQRT2", 0, {0,0,0}},
94     {M_SQRT1_2, "SQRT1_2", 0, {0,0,0}},
95     {0,0,0,{0,0,0}}
96     };
97    
98     JSClass js_MathClass = {
99     js_Math_str,
100     JSCLASS_HAS_CACHED_PROTO(JSProto_Math),
101     JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
102     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
103     JSCLASS_NO_OPTIONAL_MEMBERS
104     };
105    
106     static JSBool
107     math_abs(JSContext *cx, uintN argc, jsval *vp)
108     {
109     jsdouble x, z;
110    
111     if (argc == 0) {
112     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
113     return JS_TRUE;
114     }
115     x = js_ValueToNumber(cx, &vp[2]);
116     if (JSVAL_IS_NULL(vp[2]))
117     return JS_FALSE;
118 siliconforks 399 z = fabs(x);
119 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
120     }
121    
122     static JSBool
123     math_acos(JSContext *cx, uintN argc, jsval *vp)
124     {
125     jsdouble x, z;
126    
127     if (argc == 0) {
128     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
129     return JS_TRUE;
130     }
131     x = js_ValueToNumber(cx, &vp[2]);
132     if (JSVAL_IS_NULL(vp[2]))
133     return JS_FALSE;
134 siliconforks 399 #if defined(SOLARIS) && defined(__GNUC__)
135 siliconforks 332 if (x < -1 || 1 < x) {
136     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
137     return JS_TRUE;
138     }
139     #endif
140 siliconforks 399 z = acos(x);
141 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
142     }
143    
144     static JSBool
145     math_asin(JSContext *cx, uintN argc, jsval *vp)
146     {
147     jsdouble x, z;
148    
149     if (argc == 0) {
150     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
151     return JS_TRUE;
152     }
153     x = js_ValueToNumber(cx, &vp[2]);
154     if (JSVAL_IS_NULL(vp[2]))
155     return JS_FALSE;
156 siliconforks 399 #if defined(SOLARIS) && defined(__GNUC__)
157 siliconforks 332 if (x < -1 || 1 < x) {
158     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
159     return JS_TRUE;
160     }
161     #endif
162 siliconforks 399 z = asin(x);
163 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
164     }
165    
166     static JSBool
167     math_atan(JSContext *cx, uintN argc, jsval *vp)
168     {
169     jsdouble x, z;
170    
171     if (argc == 0) {
172     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
173     return JS_TRUE;
174     }
175     x = js_ValueToNumber(cx, &vp[2]);
176     if (JSVAL_IS_NULL(vp[2]))
177     return JS_FALSE;
178 siliconforks 399 z = atan(x);
179 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
180     }
181    
182     static JSBool
183     math_atan2(JSContext *cx, uintN argc, jsval *vp)
184     {
185     jsdouble x, y, z;
186    
187     if (argc <= 1) {
188     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
189     return JS_TRUE;
190     }
191     x = js_ValueToNumber(cx, &vp[2]);
192     if (JSVAL_IS_NULL(vp[2]))
193     return JS_FALSE;
194     y = js_ValueToNumber(cx, &vp[3]);
195     if (JSVAL_IS_NULL(vp[3]))
196     return JS_FALSE;
197     #if defined(_MSC_VER)
198     /*
199     * MSVC's atan2 does not yield the result demanded by ECMA when both x
200     * and y are infinite.
201     * - The result is a multiple of pi/4.
202     * - The sign of x determines the sign of the result.
203     * - The sign of y determines the multiplicator, 1 or 3.
204     */
205     if (JSDOUBLE_IS_INFINITE(x) && JSDOUBLE_IS_INFINITE(y)) {
206 siliconforks 399 z = js_copysign(M_PI / 4, x);
207 siliconforks 332 if (y < 0)
208     z *= 3;
209     return js_NewDoubleInRootedValue(cx, z, vp);
210     }
211     #endif
212    
213 siliconforks 399 #if defined(SOLARIS) && defined(__GNUC__)
214 siliconforks 332 if (x == 0) {
215     if (JSDOUBLE_IS_NEGZERO(y)) {
216 siliconforks 399 z = js_copysign(M_PI, x);
217 siliconforks 332 return js_NewDoubleInRootedValue(cx, z, vp);
218     }
219     if (y == 0) {
220     z = x;
221     return js_NewDoubleInRootedValue(cx, z, vp);
222     }
223     }
224     #endif
225 siliconforks 399 z = atan2(x, y);
226 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
227     }
228    
229 siliconforks 399 static JSBool
230     math_ceil(JSContext *cx, uintN argc, jsval *vp)
231 siliconforks 332 {
232     jsdouble x, z;
233    
234     if (argc == 0) {
235     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
236     return JS_TRUE;
237     }
238     x = js_ValueToNumber(cx, &vp[2]);
239     if (JSVAL_IS_NULL(vp[2]))
240     return JS_FALSE;
241 siliconforks 399 z = ceil(x);
242 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
243     }
244    
245 siliconforks 399 static JSBool
246     math_cos(JSContext *cx, uintN argc, jsval *vp)
247 siliconforks 332 {
248     jsdouble x, z;
249    
250     if (argc == 0) {
251     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
252     return JS_TRUE;
253     }
254     x = js_ValueToNumber(cx, &vp[2]);
255     if (JSVAL_IS_NULL(vp[2]))
256     return JS_FALSE;
257 siliconforks 399 z = cos(x);
258 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
259     }
260    
261     static JSBool
262     math_exp(JSContext *cx, uintN argc, jsval *vp)
263     {
264     jsdouble x, z;
265    
266     if (argc == 0) {
267     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
268     return JS_TRUE;
269     }
270     x = js_ValueToNumber(cx, &vp[2]);
271     if (JSVAL_IS_NULL(vp[2]))
272     return JS_FALSE;
273     #ifdef _WIN32
274     if (!JSDOUBLE_IS_NaN(x)) {
275     if (x == *cx->runtime->jsPositiveInfinity) {
276     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
277     return JS_TRUE;
278     }
279     if (x == *cx->runtime->jsNegativeInfinity) {
280     *vp = JSVAL_ZERO;
281     return JS_TRUE;
282     }
283     }
284     #endif
285 siliconforks 399 z = exp(x);
286 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
287     }
288    
289 siliconforks 399 static JSBool
290     math_floor(JSContext *cx, uintN argc, jsval *vp)
291 siliconforks 332 {
292     jsdouble x, z;
293    
294     if (argc == 0) {
295     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
296     return JS_TRUE;
297     }
298     x = js_ValueToNumber(cx, &vp[2]);
299     if (JSVAL_IS_NULL(vp[2]))
300     return JS_FALSE;
301 siliconforks 399 z = floor(x);
302 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
303     }
304    
305 siliconforks 399 static JSBool
306     math_log(JSContext *cx, uintN argc, jsval *vp)
307 siliconforks 332 {
308     jsdouble x, z;
309    
310     if (argc == 0) {
311     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
312     return JS_TRUE;
313     }
314     x = js_ValueToNumber(cx, &vp[2]);
315     if (JSVAL_IS_NULL(vp[2]))
316     return JS_FALSE;
317 siliconforks 399 #if defined(SOLARIS) && defined(__GNUC__)
318 siliconforks 332 if (x < 0) {
319     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
320     return JS_TRUE;
321     }
322     #endif
323 siliconforks 399 z = log(x);
324 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
325     }
326    
327 siliconforks 399 static JSBool
328     math_max(JSContext *cx, uintN argc, jsval *vp)
329 siliconforks 332 {
330     jsdouble x, z = *cx->runtime->jsNegativeInfinity;
331     jsval *argv;
332     uintN i;
333    
334     if (argc == 0) {
335     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity);
336     return JS_TRUE;
337     }
338     argv = vp + 2;
339     for (i = 0; i < argc; i++) {
340     x = js_ValueToNumber(cx, &argv[i]);
341     if (JSVAL_IS_NULL(argv[i]))
342     return JS_FALSE;
343     if (JSDOUBLE_IS_NaN(x)) {
344     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
345     return JS_TRUE;
346     }
347 siliconforks 399 if (x == 0 && x == z) {
348     if (js_copysign(1.0, z) == -1)
349     z = x;
350     } else {
351 siliconforks 332 z = (x > z) ? x : z;
352 siliconforks 399 }
353 siliconforks 332 }
354     return js_NewNumberInRootedValue(cx, z, vp);
355     }
356    
357     static JSBool
358     math_min(JSContext *cx, uintN argc, jsval *vp)
359     {
360     jsdouble x, z = *cx->runtime->jsPositiveInfinity;
361     jsval *argv;
362     uintN i;
363    
364     if (argc == 0) {
365     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity);
366     return JS_TRUE;
367     }
368     argv = vp + 2;
369     for (i = 0; i < argc; i++) {
370     x = js_ValueToNumber(cx, &argv[i]);
371     if (JSVAL_IS_NULL(argv[i]))
372     return JS_FALSE;
373     if (JSDOUBLE_IS_NaN(x)) {
374     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
375     return JS_TRUE;
376     }
377 siliconforks 399 if (x == 0 && x == z) {
378     if (js_copysign(1.0, x) == -1)
379     z = x;
380     } else {
381 siliconforks 332 z = (x < z) ? x : z;
382 siliconforks 399 }
383 siliconforks 332 }
384     return js_NewNumberInRootedValue(cx, z, vp);
385     }
386    
387 siliconforks 399 static JSBool
388     math_pow(JSContext *cx, uintN argc, jsval *vp)
389 siliconforks 332 {
390     jsdouble x, y, z;
391    
392     if (argc <= 1) {
393     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
394     return JS_TRUE;
395     }
396     x = js_ValueToNumber(cx, &vp[2]);
397     if (JSVAL_IS_NULL(vp[2]))
398     return JS_FALSE;
399     y = js_ValueToNumber(cx, &vp[3]);
400     if (JSVAL_IS_NULL(vp[3]))
401     return JS_FALSE;
402     /*
403     * Because C99 and ECMA specify different behavior for pow(),
404     * we need to wrap the libm call to make it ECMA compliant.
405     */
406     if (!JSDOUBLE_IS_FINITE(y) && (x == 1.0 || x == -1.0)) {
407     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
408     return JS_TRUE;
409     }
410     /* pow(x, +-0) is always 1, even for x = NaN. */
411     if (y == 0) {
412     *vp = JSVAL_ONE;
413     return JS_TRUE;
414     }
415 siliconforks 399 z = pow(x, y);
416 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
417     }
418    
419     /*
420     * Math.random() support, lifted from java.util.Random.java.
421     */
422     static void
423     random_setSeed(JSRuntime *rt, int64 seed)
424     {
425     int64 tmp;
426    
427     JSLL_I2L(tmp, 1000);
428     JSLL_DIV(seed, seed, tmp);
429     JSLL_XOR(tmp, seed, rt->rngMultiplier);
430     JSLL_AND(rt->rngSeed, tmp, rt->rngMask);
431     }
432    
433     void
434     js_random_init(JSRuntime *rt)
435     {
436     int64 tmp, tmp2;
437    
438     /* Do at most once. */
439     if (rt->rngInitialized)
440     return;
441     rt->rngInitialized = JS_TRUE;
442    
443     /* rt->rngMultiplier = 0x5DEECE66DL */
444     JSLL_ISHL(tmp, 0x5, 32);
445     JSLL_UI2L(tmp2, 0xDEECE66DL);
446     JSLL_OR(rt->rngMultiplier, tmp, tmp2);
447    
448     /* rt->rngAddend = 0xBL */
449     JSLL_I2L(rt->rngAddend, 0xBL);
450    
451     /* rt->rngMask = (1L << 48) - 1 */
452     JSLL_I2L(tmp, 1);
453     JSLL_SHL(tmp2, tmp, 48);
454     JSLL_SUB(rt->rngMask, tmp2, tmp);
455    
456     /* rt->rngDscale = (jsdouble)(1L << 53) */
457     JSLL_SHL(tmp2, tmp, 53);
458     JSLL_L2D(rt->rngDscale, tmp2);
459    
460     /* Finally, set the seed from current time. */
461     random_setSeed(rt, PRMJ_Now());
462     }
463    
464     static uint32
465     random_next(JSRuntime *rt, int bits)
466     {
467     int64 nextseed, tmp;
468     uint32 retval;
469    
470     JSLL_MUL(nextseed, rt->rngSeed, rt->rngMultiplier);
471     JSLL_ADD(nextseed, nextseed, rt->rngAddend);
472     JSLL_AND(nextseed, nextseed, rt->rngMask);
473     rt->rngSeed = nextseed;
474     JSLL_USHR(tmp, nextseed, 48 - bits);
475     JSLL_L2I(retval, tmp);
476     return retval;
477     }
478    
479     jsdouble
480     js_random_nextDouble(JSRuntime *rt)
481     {
482     int64 tmp, tmp2;
483     jsdouble d;
484    
485     JSLL_ISHL(tmp, random_next(rt, 26), 27);
486     JSLL_UI2L(tmp2, random_next(rt, 27));
487     JSLL_ADD(tmp, tmp, tmp2);
488     JSLL_L2D(d, tmp);
489     return d / rt->rngDscale;
490     }
491    
492 siliconforks 399 static JSBool
493     math_random(JSContext *cx, uintN argc, jsval *vp)
494 siliconforks 332 {
495     JSRuntime *rt;
496     jsdouble z;
497    
498     rt = cx->runtime;
499     JS_LOCK_RUNTIME(rt);
500     js_random_init(rt);
501     z = js_random_nextDouble(rt);
502     JS_UNLOCK_RUNTIME(rt);
503     return js_NewNumberInRootedValue(cx, z, vp);
504     }
505    
506     #if defined _WIN32 && !defined WINCE && _MSC_VER < 1400
507     /* Try to work around apparent _copysign bustage in VC6 and VC7. */
508     double
509     js_copysign(double x, double y)
510     {
511     jsdpun xu, yu;
512    
513     xu.d = x;
514     yu.d = y;
515     xu.s.hi &= ~JSDOUBLE_HI32_SIGNBIT;
516     xu.s.hi |= yu.s.hi & JSDOUBLE_HI32_SIGNBIT;
517     return xu.d;
518     }
519     #endif
520    
521     static JSBool
522     math_round(JSContext *cx, uintN argc, jsval *vp)
523     {
524     jsdouble x, z;
525    
526     if (argc == 0) {
527     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
528     return JS_TRUE;
529     }
530     x = js_ValueToNumber(cx, &vp[2]);
531     if (JSVAL_IS_NULL(vp[2]))
532     return JS_FALSE;
533 siliconforks 399 z = js_copysign(floor(x + 0.5), x);
534 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
535     }
536    
537 siliconforks 399 static JSBool
538     math_sin(JSContext *cx, uintN argc, jsval *vp)
539 siliconforks 332 {
540     jsdouble x, z;
541    
542     if (argc == 0) {
543     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
544     return JS_TRUE;
545     }
546     x = js_ValueToNumber(cx, &vp[2]);
547     if (JSVAL_IS_NULL(vp[2]))
548     return JS_FALSE;
549 siliconforks 399 z = sin(x);
550 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
551     }
552    
553 siliconforks 399 static JSBool
554     math_sqrt(JSContext *cx, uintN argc, jsval *vp)
555 siliconforks 332 {
556     jsdouble x, z;
557    
558     if (argc == 0) {
559     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
560     return JS_TRUE;
561     }
562     x = js_ValueToNumber(cx, &vp[2]);
563     if (JSVAL_IS_NULL(vp[2]))
564     return JS_FALSE;
565 siliconforks 399 z = sqrt(x);
566 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
567     }
568    
569     static JSBool
570     math_tan(JSContext *cx, uintN argc, jsval *vp)
571     {
572     jsdouble x, z;
573    
574     if (argc == 0) {
575     *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
576     return JS_TRUE;
577     }
578     x = js_ValueToNumber(cx, &vp[2]);
579     if (JSVAL_IS_NULL(vp[2]))
580     return JS_FALSE;
581 siliconforks 399 z = tan(x);
582 siliconforks 332 return js_NewNumberInRootedValue(cx, z, vp);
583     }
584    
585     #if JS_HAS_TOSOURCE
586     static JSBool
587     math_toSource(JSContext *cx, uintN argc, jsval *vp)
588     {
589     *vp = ATOM_KEY(CLASS_ATOM(cx, Math));
590     return JS_TRUE;
591     }
592     #endif
593    
594 siliconforks 399 #ifdef JS_TRACER
595    
596     #define MATH_BUILTIN_1(name) \
597     static jsdouble FASTCALL math_##name##_tn(jsdouble d) { return name(d); } \
598     JS_DEFINE_TRCINFO_1(math_##name, \
599     (1, (static, DOUBLE, math_##name##_tn, DOUBLE, 1, 1)))
600    
601     MATH_BUILTIN_1(sin)
602     MATH_BUILTIN_1(cos)
603     MATH_BUILTIN_1(sqrt)
604     MATH_BUILTIN_1(floor)
605     MATH_BUILTIN_1(ceil)
606    
607     static jsdouble FASTCALL
608     math_abs_tn(jsdouble d)
609     {
610     return fabs(d);
611     }
612    
613     static jsdouble FASTCALL
614     math_log_tn(jsdouble d)
615     {
616     #if defined(SOLARIS) && defined(__GNUC__)
617     if (d < 0)
618     return js_NaN;
619     #endif
620     return log(d);
621     }
622    
623     static jsdouble FASTCALL
624     math_max_tn(jsdouble d, jsdouble p)
625     {
626     if (JSDOUBLE_IS_NaN(d) || JSDOUBLE_IS_NaN(p))
627     return js_NaN;
628    
629     if (p == 0 && p == d) {
630     if (js_copysign(1.0, d) == -1)
631     return p;
632     return d;
633     }
634     return (p > d) ? p : d;
635     }
636    
637     static jsdouble FASTCALL
638     math_pow_tn(jsdouble d, jsdouble p)
639     {
640     if (!JSDOUBLE_IS_FINITE(p) && (d == 1.0 || d == -1.0))
641     return js_NaN;
642     if (p == 0)
643     return 1.0;
644     return pow(d, p);
645     }
646    
647     static jsdouble FASTCALL
648     math_random_tn(JSRuntime* rt)
649     {
650     JS_LOCK_RUNTIME(rt);
651     js_random_init(rt);
652     jsdouble z = js_random_nextDouble(rt);
653     JS_UNLOCK_RUNTIME(rt);
654     return z;
655     }
656    
657     static jsdouble FASTCALL
658     math_round_tn(jsdouble x)
659     {
660     return js_copysign(floor(x + 0.5), x);
661     }
662    
663     JS_DEFINE_TRCINFO_1(math_abs,
664     (1, (static, DOUBLE, math_abs_tn, DOUBLE, 1, 1)))
665     JS_DEFINE_TRCINFO_1(math_log,
666     (1, (static, DOUBLE, math_log_tn, DOUBLE, 1, 1)))
667     JS_DEFINE_TRCINFO_1(math_max,
668     (2, (static, DOUBLE, math_max_tn, DOUBLE, DOUBLE, 1, 1)))
669     JS_DEFINE_TRCINFO_1(math_pow,
670     (2, (static, DOUBLE, math_pow_tn, DOUBLE, DOUBLE, 1, 1)))
671     JS_DEFINE_TRCINFO_1(math_random,
672     (1, (static, DOUBLE, math_random_tn, RUNTIME, 0, 0)))
673     JS_DEFINE_TRCINFO_1(math_round,
674     (1, (static, DOUBLE, math_round_tn, DOUBLE, 1, 1)))
675    
676     #endif /* JS_TRACER */
677    
678 siliconforks 332 static JSFunctionSpec math_static_methods[] = {
679     #if JS_HAS_TOSOURCE
680 siliconforks 399 JS_FN(js_toSource_str, math_toSource, 0, 0),
681 siliconforks 332 #endif
682 siliconforks 399 JS_TN("abs", math_abs, 1, 0, math_abs_trcinfo),
683     JS_FN("acos", math_acos, 1, 0),
684     JS_FN("asin", math_asin, 1, 0),
685     JS_FN("atan", math_atan, 1, 0),
686     JS_FN("atan2", math_atan2, 2, 0),
687     JS_TN("ceil", math_ceil, 1, 0, math_ceil_trcinfo),
688     JS_TN("cos", math_cos, 1, 0, math_cos_trcinfo),
689     JS_FN("exp", math_exp, 1, 0),
690     JS_TN("floor", math_floor, 1, 0, math_floor_trcinfo),
691     JS_TN("log", math_log, 1, 0, math_log_trcinfo),
692     JS_TN("max", math_max, 2, 0, math_max_trcinfo),
693     JS_FN("min", math_min, 2, 0),
694     JS_TN("pow", math_pow, 2, 0, math_pow_trcinfo),
695     JS_TN("random", math_random, 0, 0, math_random_trcinfo),
696     JS_TN("round", math_round, 1, 0, math_round_trcinfo),
697     JS_TN("sin", math_sin, 1, 0, math_sin_trcinfo),
698     JS_TN("sqrt", math_sqrt, 1, 0, math_sqrt_trcinfo),
699     JS_FN("tan", math_tan, 1, 0),
700 siliconforks 332 JS_FS_END
701     };
702    
703     JSObject *
704     js_InitMathClass(JSContext *cx, JSObject *obj)
705     {
706     JSObject *Math;
707    
708     Math = JS_NewObject(cx, &js_MathClass, NULL, obj);
709     if (!Math)
710     return NULL;
711     if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math),
712     JS_PropertyStub, JS_PropertyStub,
713     JSPROP_READONLY | JSPROP_PERMANENT))
714     return NULL;
715    
716     if (!JS_DefineFunctions(cx, Math, math_static_methods))
717     return NULL;
718     if (!JS_DefineConstDoubles(cx, Math, math_constants))
719     return NULL;
720     return Math;
721     }

  ViewVC Help
Powered by ViewVC 1.1.24