1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 // Keep reference to original values of some global properties. This
30 // has the added benefit that the code in this file is isolated from
31 // changes to these properties.
32 var $floor = MathFloor;
35 // Instance class name can only be set on functions. That is the only
36 // purpose for MathConstructor.
37 function MathConstructor() {}
38 %FunctionSetInstanceClassName(MathConstructor, 'Math');
39 var $Math = new MathConstructor();
40 $Math.__proto__ = $Object.prototype;
41 %SetProperty(global, "Math", $Math, DONT_ENUM);
43 // ECMA 262 - 15.8.2.1
45 if (%_IsSmi(x)) return x >= 0 ? x : -x;
46 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
47 if (x === 0) return 0; // To handle -0.
48 return x > 0 ? x : -x;
51 // ECMA 262 - 15.8.2.2
52 function MathAcos(x) {
53 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
57 // ECMA 262 - 15.8.2.3
58 function MathAsin(x) {
59 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
63 // ECMA 262 - 15.8.2.4
64 function MathAtan(x) {
65 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
69 // ECMA 262 - 15.8.2.5
70 // The naming of y and x matches the spec, as does the order in which
71 // ToNumber (valueOf) is called.
72 function MathAtan2(y, x) {
73 if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
74 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
75 return %Math_atan2(y, x);
78 // ECMA 262 - 15.8.2.6
79 function MathCeil(x) {
80 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
84 // ECMA 262 - 15.8.2.7
86 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
90 // ECMA 262 - 15.8.2.8
92 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
96 // ECMA 262 - 15.8.2.9
97 function MathFloor(x) {
98 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
99 // It's more common to call this with a positive number that's out
100 // of range than negative numbers; check the upper bound first.
101 if (x < 0x80000000 && x > 0) {
102 // Numbers in the range [0, 2^31) can be floored by converting
103 // them to an unsigned 32-bit value using the shift operator.
104 // We avoid doing so for -0, because the result of Math.floor(-0)
105 // has to be -0, which wouldn't be the case with the shift.
108 return %Math_floor(x);
112 // ECMA 262 - 15.8.2.10
113 function MathLog(x) {
114 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
118 // ECMA 262 - 15.8.2.11
119 function MathMax(arg1, arg2) { // length == 2
120 var length = %_ArgumentsLength();
122 if (!IS_NUMBER(arg1)) arg1 = NonNumberToNumber(arg1);
123 if (!IS_NUMBER(arg2)) arg2 = NonNumberToNumber(arg2);
124 if (arg2 > arg1) return arg2;
125 if (arg1 > arg2) return arg1;
127 // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can be
128 // a Smi or a heap number.
129 return (arg1 == 0 && !%_IsSmi(arg1) && 1 / arg1 < 0) ? arg2 : arg1;
131 // All comparisons failed, one of the arguments must be NaN.
132 return 0/0; // Compiler constant-folds this to NaN.
135 return -1/0; // Compiler constant-folds this to -Infinity.
138 if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
139 if (NUMBER_IS_NAN(r)) return r;
140 for (var i = 1; i < length; i++) {
141 var n = %_Arguments(i);
142 if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
143 if (NUMBER_IS_NAN(n)) return n;
144 // Make sure +0 is considered greater than -0. -0 is never a Smi, +0 can be
145 // a Smi or heap number.
146 if (n > r || (r == 0 && n == 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
151 // ECMA 262 - 15.8.2.12
152 function MathMin(arg1, arg2) { // length == 2
153 var length = %_ArgumentsLength();
155 if (!IS_NUMBER(arg1)) arg1 = NonNumberToNumber(arg1);
156 if (!IS_NUMBER(arg2)) arg2 = NonNumberToNumber(arg2);
157 if (arg2 > arg1) return arg1;
158 if (arg1 > arg2) return arg2;
160 // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can be
161 // a Smi or a heap number.
162 return (arg1 == 0 && !%_IsSmi(arg1) && 1 / arg1 < 0) ? arg1 : arg2;
164 // All comparisons failed, one of the arguments must be NaN.
165 return 0/0; // Compiler constant-folds this to NaN.
168 return 1/0; // Compiler constant-folds this to Infinity.
171 if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
172 if (NUMBER_IS_NAN(r)) return r;
173 for (var i = 1; i < length; i++) {
174 var n = %_Arguments(i);
175 if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
176 if (NUMBER_IS_NAN(n)) return n;
177 // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can be a
178 // Smi or a heap number.
179 if (n < r || (r == 0 && n == 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
184 // ECMA 262 - 15.8.2.13
185 function MathPow(x, y) {
186 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
187 if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
188 return %_MathPow(x, y);
191 // ECMA 262 - 15.8.2.14
192 function MathRandom() {
193 return %_RandomHeapNumber();
196 // ECMA 262 - 15.8.2.15
197 function MathRound(x) {
198 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
199 return %RoundNumber(x);
202 // ECMA 262 - 15.8.2.16
203 function MathSin(x) {
204 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
208 // ECMA 262 - 15.8.2.17
209 function MathSqrt(x) {
210 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
211 return %_MathSqrt(x);
214 // ECMA 262 - 15.8.2.18
215 function MathTan(x) {
216 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
221 // -------------------------------------------------------------------
223 function SetUpMath() {
224 %CheckIsBootstrapping();
225 // Set up math constants.
226 // ECMA-262, section 15.8.1.1.
227 %OptimizeObjectForAddingMultipleProperties($Math, 8);
230 2.7182818284590452354,
231 DONT_ENUM | DONT_DELETE | READ_ONLY);
232 // ECMA-262, section 15.8.1.2.
236 DONT_ENUM | DONT_DELETE | READ_ONLY);
237 // ECMA-262, section 15.8.1.3.
241 DONT_ENUM | DONT_DELETE | READ_ONLY);
242 // ECMA-262, section 15.8.1.4.
246 DONT_ENUM | DONT_DELETE | READ_ONLY);
250 DONT_ENUM | DONT_DELETE | READ_ONLY);
254 DONT_ENUM | DONT_DELETE | READ_ONLY);
258 DONT_ENUM | DONT_DELETE | READ_ONLY);
262 DONT_ENUM | DONT_DELETE | READ_ONLY);
263 %ToFastProperties($Math);
265 // Set up non-enumerable functions of the Math object and
267 InstallFunctions($Math, DONT_ENUM, $Array(
268 "random", MathRandom,