179 |
return js_NewNumberInRootedValue(cx, z, vp); |
return js_NewNumberInRootedValue(cx, z, vp); |
180 |
} |
} |
181 |
|
|
182 |
static JSBool |
static inline jsdouble JS_FASTCALL |
183 |
math_atan2(JSContext *cx, uintN argc, jsval *vp) |
math_atan2_kernel(jsdouble x, jsdouble y) |
184 |
{ |
{ |
|
jsdouble x, y, z; |
|
|
|
|
|
if (argc <= 1) { |
|
|
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); |
|
|
return JS_TRUE; |
|
|
} |
|
|
x = js_ValueToNumber(cx, &vp[2]); |
|
|
if (JSVAL_IS_NULL(vp[2])) |
|
|
return JS_FALSE; |
|
|
y = js_ValueToNumber(cx, &vp[3]); |
|
|
if (JSVAL_IS_NULL(vp[3])) |
|
|
return JS_FALSE; |
|
185 |
#if defined(_MSC_VER) |
#if defined(_MSC_VER) |
186 |
/* |
/* |
187 |
* MSVC's atan2 does not yield the result demanded by ECMA when both x |
* MSVC's atan2 does not yield the result demanded by ECMA when both x |
191 |
* - The sign of y determines the multiplicator, 1 or 3. |
* - The sign of y determines the multiplicator, 1 or 3. |
192 |
*/ |
*/ |
193 |
if (JSDOUBLE_IS_INFINITE(x) && JSDOUBLE_IS_INFINITE(y)) { |
if (JSDOUBLE_IS_INFINITE(x) && JSDOUBLE_IS_INFINITE(y)) { |
194 |
z = js_copysign(M_PI / 4, x); |
jsdouble z = js_copysign(M_PI / 4, x); |
195 |
if (y < 0) |
if (y < 0) |
196 |
z *= 3; |
z *= 3; |
197 |
return js_NewDoubleInRootedValue(cx, z, vp); |
return z; |
198 |
} |
} |
199 |
#endif |
#endif |
200 |
|
|
201 |
#if defined(SOLARIS) && defined(__GNUC__) |
#if defined(SOLARIS) && defined(__GNUC__) |
202 |
if (x == 0) { |
if (x == 0) { |
203 |
if (JSDOUBLE_IS_NEGZERO(y)) { |
if (JSDOUBLE_IS_NEGZERO(y)) |
204 |
z = js_copysign(M_PI, x); |
return js_copysign(M_PI, x); |
205 |
return js_NewDoubleInRootedValue(cx, z, vp); |
if (y == 0) |
206 |
} |
return x; |
|
if (y == 0) { |
|
|
z = x; |
|
|
return js_NewDoubleInRootedValue(cx, z, vp); |
|
|
} |
|
207 |
} |
} |
208 |
#endif |
#endif |
209 |
z = atan2(x, y); |
return atan2(x, y); |
210 |
return js_NewNumberInRootedValue(cx, z, vp); |
} |
211 |
|
|
212 |
|
static JSBool |
213 |
|
math_atan2(JSContext *cx, uintN argc, jsval *vp) |
214 |
|
{ |
215 |
|
jsdouble x, y; |
216 |
|
|
217 |
|
if (argc <= 1) { |
218 |
|
*vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); |
219 |
|
return JS_TRUE; |
220 |
|
} |
221 |
|
x = js_ValueToNumber(cx, &vp[2]); |
222 |
|
if (JSVAL_IS_NULL(vp[2])) |
223 |
|
return JS_FALSE; |
224 |
|
y = js_ValueToNumber(cx, &vp[3]); |
225 |
|
if (JSVAL_IS_NULL(vp[3])) |
226 |
|
return JS_FALSE; |
227 |
|
return js_NewNumberInRootedValue(cx, math_atan2_kernel (x, y), vp); |
228 |
|
} |
229 |
|
|
230 |
|
static inline jsdouble JS_FASTCALL |
231 |
|
math_ceil_kernel(jsdouble x) |
232 |
|
{ |
233 |
|
#ifdef __APPLE__ |
234 |
|
if (x < 0 && x > -1.0) |
235 |
|
return js_copysign(0, -1); |
236 |
|
#endif |
237 |
|
return ceil(x); |
238 |
} |
} |
239 |
|
|
240 |
static JSBool |
static JSBool |
249 |
x = js_ValueToNumber(cx, &vp[2]); |
x = js_ValueToNumber(cx, &vp[2]); |
250 |
if (JSVAL_IS_NULL(vp[2])) |
if (JSVAL_IS_NULL(vp[2])) |
251 |
return JS_FALSE; |
return JS_FALSE; |
252 |
z = ceil(x); |
z = math_ceil_kernel(x); |
253 |
return js_NewNumberInRootedValue(cx, z, vp); |
return js_NewNumberInRootedValue(cx, z, vp); |
254 |
} |
} |
255 |
|
|
604 |
|
|
605 |
#ifdef JS_TRACER |
#ifdef JS_TRACER |
606 |
|
|
607 |
#define MATH_BUILTIN_1(name) \ |
#define MATH_BUILTIN_1(name) MATH_BUILTIN_CFUN_1(name, name) |
608 |
static jsdouble FASTCALL math_##name##_tn(jsdouble d) { return name(d); } \ |
#define MATH_BUILTIN_CFUN_1(name, cfun) \ |
609 |
|
static jsdouble FASTCALL math_##name##_tn(jsdouble d) { return cfun(d); } \ |
610 |
JS_DEFINE_TRCINFO_1(math_##name, \ |
JS_DEFINE_TRCINFO_1(math_##name, \ |
611 |
(1, (static, DOUBLE, math_##name##_tn, DOUBLE, 1, 1))) |
(1, (static, DOUBLE, math_##name##_tn, DOUBLE, 1, 1))) |
612 |
|
|
613 |
|
MATH_BUILTIN_CFUN_1(abs, fabs) |
614 |
|
MATH_BUILTIN_1(atan) |
615 |
MATH_BUILTIN_1(sin) |
MATH_BUILTIN_1(sin) |
616 |
MATH_BUILTIN_1(cos) |
MATH_BUILTIN_1(cos) |
617 |
MATH_BUILTIN_1(sqrt) |
MATH_BUILTIN_1(sqrt) |
618 |
MATH_BUILTIN_1(floor) |
MATH_BUILTIN_1(floor) |
619 |
MATH_BUILTIN_1(ceil) |
MATH_BUILTIN_1(tan) |
620 |
|
|
621 |
static jsdouble FASTCALL |
static jsdouble FASTCALL |
622 |
math_abs_tn(jsdouble d) |
math_acos_tn(jsdouble d) |
623 |
{ |
{ |
624 |
return fabs(d); |
#if defined(SOLARIS) && defined(__GNUC__) |
625 |
|
if (d < -1 || 1 < d) { |
626 |
|
return js_NaN; |
627 |
|
} |
628 |
|
#endif |
629 |
|
return acos(d); |
630 |
|
} |
631 |
|
|
632 |
|
static jsdouble FASTCALL |
633 |
|
math_asin_tn(jsdouble d) |
634 |
|
{ |
635 |
|
#if defined(SOLARIS) && defined(__GNUC__) |
636 |
|
if (d < -1 || 1 < d) { |
637 |
|
return js_NaN; |
638 |
|
} |
639 |
|
#endif |
640 |
|
return asin(d); |
641 |
} |
} |
642 |
|
|
643 |
|
#ifdef _WIN32 |
644 |
|
|
645 |
|
static jsdouble FASTCALL |
646 |
|
math_exp_tn(JSContext *cx, jsdouble d) |
647 |
|
{ |
648 |
|
if (!JSDOUBLE_IS_NaN(d)) { |
649 |
|
if (d == *cx->runtime->jsPositiveInfinity) { |
650 |
|
return *cx->runtime->jsPositiveInfinity; |
651 |
|
} |
652 |
|
if (d == *cx->runtime->jsNegativeInfinity) { |
653 |
|
return 0.0; |
654 |
|
} |
655 |
|
} |
656 |
|
return exp(d); |
657 |
|
} |
658 |
|
|
659 |
|
JS_DEFINE_TRCINFO_1(math_exp, |
660 |
|
(2, (static, DOUBLE, math_exp_tn, CONTEXT, DOUBLE, 1, 1))) |
661 |
|
|
662 |
|
#else |
663 |
|
|
664 |
|
MATH_BUILTIN_1(exp) |
665 |
|
|
666 |
|
#endif |
667 |
|
|
668 |
static jsdouble FASTCALL |
static jsdouble FASTCALL |
669 |
math_log_tn(jsdouble d) |
math_log_tn(jsdouble d) |
670 |
{ |
{ |
682 |
return js_NaN; |
return js_NaN; |
683 |
|
|
684 |
if (p == 0 && p == d) { |
if (p == 0 && p == d) { |
685 |
|
// Max prefers 0.0 to -0.0. |
686 |
if (js_copysign(1.0, d) == -1) |
if (js_copysign(1.0, d) == -1) |
687 |
return p; |
return p; |
688 |
return d; |
return d; |
691 |
} |
} |
692 |
|
|
693 |
static jsdouble FASTCALL |
static jsdouble FASTCALL |
694 |
|
math_min_tn(jsdouble d, jsdouble p) |
695 |
|
{ |
696 |
|
if (JSDOUBLE_IS_NaN(d) || JSDOUBLE_IS_NaN(p)) |
697 |
|
return js_NaN; |
698 |
|
|
699 |
|
if (p == 0 && p == d) { |
700 |
|
// Min prefers -0.0 to 0.0. |
701 |
|
if (js_copysign (1.0, p) == -1) |
702 |
|
return p; |
703 |
|
return d; |
704 |
|
} |
705 |
|
return (p < d) ? p : d; |
706 |
|
} |
707 |
|
|
708 |
|
static jsdouble FASTCALL |
709 |
math_pow_tn(jsdouble d, jsdouble p) |
math_pow_tn(jsdouble d, jsdouble p) |
710 |
{ |
{ |
711 |
if (!JSDOUBLE_IS_FINITE(p) && (d == 1.0 || d == -1.0)) |
if (!JSDOUBLE_IS_FINITE(p) && (d == 1.0 || d == -1.0)) |
731 |
return js_copysign(floor(x + 0.5), x); |
return js_copysign(floor(x + 0.5), x); |
732 |
} |
} |
733 |
|
|
734 |
JS_DEFINE_TRCINFO_1(math_abs, |
static jsdouble FASTCALL |
735 |
(1, (static, DOUBLE, math_abs_tn, DOUBLE, 1, 1))) |
math_ceil_tn(jsdouble x) |
736 |
|
{ |
737 |
|
return math_ceil_kernel(x); |
738 |
|
} |
739 |
|
|
740 |
|
JS_DEFINE_TRCINFO_1(math_acos, |
741 |
|
(1, (static, DOUBLE, math_acos_tn, DOUBLE, 1, 1))) |
742 |
|
JS_DEFINE_TRCINFO_1(math_asin, |
743 |
|
(1, (static, DOUBLE, math_asin_tn, DOUBLE, 1, 1))) |
744 |
|
JS_DEFINE_TRCINFO_1(math_atan2, |
745 |
|
(2, (static, DOUBLE, math_atan2_kernel, DOUBLE, DOUBLE, 1, 1))) |
746 |
JS_DEFINE_TRCINFO_1(math_log, |
JS_DEFINE_TRCINFO_1(math_log, |
747 |
(1, (static, DOUBLE, math_log_tn, DOUBLE, 1, 1))) |
(1, (static, DOUBLE, math_log_tn, DOUBLE, 1, 1))) |
748 |
JS_DEFINE_TRCINFO_1(math_max, |
JS_DEFINE_TRCINFO_1(math_max, |
749 |
(2, (static, DOUBLE, math_max_tn, DOUBLE, DOUBLE, 1, 1))) |
(2, (static, DOUBLE, math_max_tn, DOUBLE, DOUBLE, 1, 1))) |
750 |
|
JS_DEFINE_TRCINFO_1(math_min, |
751 |
|
(2, (static, DOUBLE, math_min_tn, DOUBLE, DOUBLE, 1, 1))) |
752 |
JS_DEFINE_TRCINFO_1(math_pow, |
JS_DEFINE_TRCINFO_1(math_pow, |
753 |
(2, (static, DOUBLE, math_pow_tn, DOUBLE, DOUBLE, 1, 1))) |
(2, (static, DOUBLE, math_pow_tn, DOUBLE, DOUBLE, 1, 1))) |
754 |
JS_DEFINE_TRCINFO_1(math_random, |
JS_DEFINE_TRCINFO_1(math_random, |
755 |
(1, (static, DOUBLE, math_random_tn, RUNTIME, 0, 0))) |
(1, (static, DOUBLE, math_random_tn, RUNTIME, 0, 0))) |
756 |
JS_DEFINE_TRCINFO_1(math_round, |
JS_DEFINE_TRCINFO_1(math_round, |
757 |
(1, (static, DOUBLE, math_round_tn, DOUBLE, 1, 1))) |
(1, (static, DOUBLE, math_round_tn, DOUBLE, 1, 1))) |
758 |
|
JS_DEFINE_TRCINFO_1(math_ceil, |
759 |
|
(1, (static, DOUBLE, math_ceil_tn, DOUBLE, 1, 1))) |
760 |
|
|
761 |
#endif /* JS_TRACER */ |
#endif /* JS_TRACER */ |
762 |
|
|
765 |
JS_FN(js_toSource_str, math_toSource, 0, 0), |
JS_FN(js_toSource_str, math_toSource, 0, 0), |
766 |
#endif |
#endif |
767 |
JS_TN("abs", math_abs, 1, 0, math_abs_trcinfo), |
JS_TN("abs", math_abs, 1, 0, math_abs_trcinfo), |
768 |
JS_FN("acos", math_acos, 1, 0), |
JS_TN("acos", math_acos, 1, 0, math_acos_trcinfo), |
769 |
JS_FN("asin", math_asin, 1, 0), |
JS_TN("asin", math_asin, 1, 0, math_asin_trcinfo), |
770 |
JS_FN("atan", math_atan, 1, 0), |
JS_TN("atan", math_atan, 1, 0, math_atan_trcinfo), |
771 |
JS_FN("atan2", math_atan2, 2, 0), |
JS_TN("atan2", math_atan2, 2, 0, math_atan2_trcinfo), |
772 |
JS_TN("ceil", math_ceil, 1, 0, math_ceil_trcinfo), |
JS_TN("ceil", math_ceil, 1, 0, math_ceil_trcinfo), |
773 |
JS_TN("cos", math_cos, 1, 0, math_cos_trcinfo), |
JS_TN("cos", math_cos, 1, 0, math_cos_trcinfo), |
774 |
JS_FN("exp", math_exp, 1, 0), |
JS_TN("exp", math_exp, 1, 0, math_exp_trcinfo), |
775 |
JS_TN("floor", math_floor, 1, 0, math_floor_trcinfo), |
JS_TN("floor", math_floor, 1, 0, math_floor_trcinfo), |
776 |
JS_TN("log", math_log, 1, 0, math_log_trcinfo), |
JS_TN("log", math_log, 1, 0, math_log_trcinfo), |
777 |
JS_TN("max", math_max, 2, 0, math_max_trcinfo), |
JS_TN("max", math_max, 2, 0, math_max_trcinfo), |
778 |
JS_FN("min", math_min, 2, 0), |
JS_TN("min", math_min, 2, 0, math_min_trcinfo), |
779 |
JS_TN("pow", math_pow, 2, 0, math_pow_trcinfo), |
JS_TN("pow", math_pow, 2, 0, math_pow_trcinfo), |
780 |
JS_TN("random", math_random, 0, 0, math_random_trcinfo), |
JS_TN("random", math_random, 0, 0, math_random_trcinfo), |
781 |
JS_TN("round", math_round, 1, 0, math_round_trcinfo), |
JS_TN("round", math_round, 1, 0, math_round_trcinfo), |
782 |
JS_TN("sin", math_sin, 1, 0, math_sin_trcinfo), |
JS_TN("sin", math_sin, 1, 0, math_sin_trcinfo), |
783 |
JS_TN("sqrt", math_sqrt, 1, 0, math_sqrt_trcinfo), |
JS_TN("sqrt", math_sqrt, 1, 0, math_sqrt_trcinfo), |
784 |
JS_FN("tan", math_tan, 1, 0), |
JS_TN("tan", math_tan, 1, 0, math_tan_trcinfo), |
785 |
JS_FS_END |
JS_FS_END |
786 |
}; |
}; |
787 |
|
|
794 |
if (!Math) |
if (!Math) |
795 |
return NULL; |
return NULL; |
796 |
if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math), |
if (!JS_DefineProperty(cx, obj, js_Math_str, OBJECT_TO_JSVAL(Math), |
797 |
JS_PropertyStub, JS_PropertyStub, |
JS_PropertyStub, JS_PropertyStub, 0)) { |
|
JSPROP_READONLY | JSPROP_PERMANENT)) |
|
798 |
return NULL; |
return NULL; |
799 |
|
} |
800 |
|
|
801 |
if (!JS_DefineFunctions(cx, Math, math_static_methods)) |
if (!JS_DefineFunctions(cx, Math, math_static_methods)) |
802 |
return NULL; |
return NULL; |