PageRenderTime 162ms CodeModel.GetById 10ms app.highlight 132ms RepoModel.GetById 13ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/jsmath.cpp

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
C++ | 721 lines | 584 code | 74 blank | 63 comment | 122 complexity | 874c54a9f3986f5c33d8559d8bf47911 MD5 | raw file
  1/* -*- 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#include "jsbuiltins.h"
 52#include "jscntxt.h"
 53#include "jsversion.h"
 54#include "jslock.h"
 55#include "jsmath.h"
 56#include "jsnum.h"
 57#include "jsobj.h"
 58
 59extern jsdouble js_NaN;
 60
 61#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
 86static 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
 98JSClass 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
106static JSBool
107math_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    z = fabs(x);
119    return js_NewNumberInRootedValue(cx, z, vp);
120}
121
122static JSBool
123math_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#if defined(SOLARIS) && defined(__GNUC__)
135    if (x < -1 || 1 < x) {
136        *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
137        return JS_TRUE;
138    }
139#endif
140    z = acos(x);
141    return js_NewNumberInRootedValue(cx, z, vp);
142}
143
144static JSBool
145math_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#if defined(SOLARIS) && defined(__GNUC__)
157    if (x < -1 || 1 < x) {
158        *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
159        return JS_TRUE;
160    }
161#endif
162    z = asin(x);
163    return js_NewNumberInRootedValue(cx, z, vp);
164}
165
166static JSBool
167math_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    z = atan(x);
179    return js_NewNumberInRootedValue(cx, z, vp);
180}
181
182static JSBool
183math_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        z = js_copysign(M_PI / 4, x);
207        if (y < 0)
208            z *= 3;
209        return js_NewDoubleInRootedValue(cx, z, vp);
210    }
211#endif
212
213#if defined(SOLARIS) && defined(__GNUC__)
214    if (x == 0) {
215        if (JSDOUBLE_IS_NEGZERO(y)) {
216            z = js_copysign(M_PI, x);
217            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    z = atan2(x, y);
226    return js_NewNumberInRootedValue(cx, z, vp);
227}
228
229static JSBool
230math_ceil(JSContext *cx, uintN argc, jsval *vp)
231{
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    z = ceil(x);
242    return js_NewNumberInRootedValue(cx, z, vp);
243}
244
245static JSBool
246math_cos(JSContext *cx, uintN argc, jsval *vp)
247{
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    z = cos(x);
258    return js_NewNumberInRootedValue(cx, z, vp);
259}
260
261static JSBool
262math_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    z = exp(x);
286    return js_NewNumberInRootedValue(cx, z, vp);
287}
288
289static JSBool
290math_floor(JSContext *cx, uintN argc, jsval *vp)
291{
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    z = floor(x);
302    return js_NewNumberInRootedValue(cx, z, vp);
303}
304
305static JSBool
306math_log(JSContext *cx, uintN argc, jsval *vp)
307{
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#if defined(SOLARIS) && defined(__GNUC__)
318    if (x < 0) {
319        *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
320        return JS_TRUE;
321    }
322#endif
323    z = log(x);
324    return js_NewNumberInRootedValue(cx, z, vp);
325}
326
327static JSBool
328math_max(JSContext *cx, uintN argc, jsval *vp)
329{
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        if (x == 0 && x == z) {
348            if (js_copysign(1.0, z) == -1)
349                z = x;
350        } else {
351            z = (x > z) ? x : z;
352        }
353    }
354    return js_NewNumberInRootedValue(cx, z, vp);
355}
356
357static JSBool
358math_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        if (x == 0 && x == z) {
378            if (js_copysign(1.0, x) == -1)
379                z = x;
380        } else {
381            z = (x < z) ? x : z;
382        }
383    }
384    return js_NewNumberInRootedValue(cx, z, vp);
385}
386
387static JSBool
388math_pow(JSContext *cx, uintN argc, jsval *vp)
389{
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    z = pow(x, y);
416    return js_NewNumberInRootedValue(cx, z, vp);
417}
418
419/*
420 * Math.random() support, lifted from java.util.Random.java.
421 */
422static void
423random_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
433void
434js_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
464static uint32
465random_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
479jsdouble
480js_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
492static JSBool
493math_random(JSContext *cx, uintN argc, jsval *vp)
494{
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. */
508double
509js_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
521static JSBool
522math_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    z = js_copysign(floor(x + 0.5), x);
534    return js_NewNumberInRootedValue(cx, z, vp);
535}
536
537static JSBool
538math_sin(JSContext *cx, uintN argc, jsval *vp)
539{
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    z = sin(x);
550    return js_NewNumberInRootedValue(cx, z, vp);
551}
552
553static JSBool
554math_sqrt(JSContext *cx, uintN argc, jsval *vp)
555{
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    z = sqrt(x);
566    return js_NewNumberInRootedValue(cx, z, vp);
567}
568
569static JSBool
570math_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    z = tan(x);
582    return js_NewNumberInRootedValue(cx, z, vp);
583}
584
585#if JS_HAS_TOSOURCE
586static JSBool
587math_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#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
601MATH_BUILTIN_1(sin)
602MATH_BUILTIN_1(cos)
603MATH_BUILTIN_1(sqrt)
604MATH_BUILTIN_1(floor)
605MATH_BUILTIN_1(ceil)
606
607static jsdouble FASTCALL
608math_abs_tn(jsdouble d)
609{
610    return fabs(d);
611}
612
613static jsdouble FASTCALL
614math_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
623static jsdouble FASTCALL
624math_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
637static jsdouble FASTCALL
638math_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
647static jsdouble FASTCALL
648math_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
657static jsdouble FASTCALL
658math_round_tn(jsdouble x)
659{
660    return js_copysign(floor(x + 0.5), x);
661}
662
663JS_DEFINE_TRCINFO_1(math_abs,
664    (1, (static, DOUBLE, math_abs_tn, DOUBLE,           1, 1)))
665JS_DEFINE_TRCINFO_1(math_log,
666    (1, (static, DOUBLE, math_log_tn, DOUBLE,           1, 1)))
667JS_DEFINE_TRCINFO_1(math_max,
668    (2, (static, DOUBLE, math_max_tn, DOUBLE, DOUBLE,   1, 1)))
669JS_DEFINE_TRCINFO_1(math_pow,
670    (2, (static, DOUBLE, math_pow_tn, DOUBLE, DOUBLE,   1, 1)))
671JS_DEFINE_TRCINFO_1(math_random,
672    (1, (static, DOUBLE, math_random_tn, RUNTIME,       0, 0)))
673JS_DEFINE_TRCINFO_1(math_round,
674    (1, (static, DOUBLE, math_round_tn, DOUBLE,         1, 1)))
675
676#endif /* JS_TRACER */
677
678static JSFunctionSpec math_static_methods[] = {
679#if JS_HAS_TOSOURCE
680    JS_FN(js_toSource_str,  math_toSource,        0, 0),
681#endif
682    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    JS_FS_END
701};
702
703JSObject *
704js_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}