• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2006-2008 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
4// met:
5//
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.
15//
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.
27
28
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.
32const $floor = MathFloor;
33const $random = MathRandom;
34const $abs = MathAbs;
35
36// Instance class name can only be set on functions. That is the only
37// purpose for MathConstructor.
38function MathConstructor() {}
39%FunctionSetInstanceClassName(MathConstructor, 'Math');
40const $Math = new MathConstructor();
41$Math.__proto__ = global.Object.prototype;
42%SetProperty(global, "Math", $Math, DONT_ENUM);
43
44// ECMA 262 - 15.8.2.1
45function MathAbs(x) {
46  if (%_IsSmi(x)) return x >= 0 ? x : -x;
47  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
48  if (x === 0) return 0;  // To handle -0.
49  return x > 0 ? x : -x;
50}
51
52// ECMA 262 - 15.8.2.2
53function MathAcos(x) {
54  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
55  return %Math_acos(x);
56}
57
58// ECMA 262 - 15.8.2.3
59function MathAsin(x) {
60  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
61  return %Math_asin(x);
62}
63
64// ECMA 262 - 15.8.2.4
65function MathAtan(x) {
66  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
67  return %Math_atan(x);
68}
69
70// ECMA 262 - 15.8.2.5
71// The naming of y and x matches the spec, as does the order in which
72// ToNumber (valueOf) is called.
73function MathAtan2(y, x) {
74  if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
75  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
76  return %Math_atan2(y, x);
77}
78
79// ECMA 262 - 15.8.2.6
80function MathCeil(x) {
81  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
82  return %Math_ceil(x);
83}
84
85// ECMA 262 - 15.8.2.7
86function MathCos(x) {
87  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
88  return %_MathCos(x);
89}
90
91// ECMA 262 - 15.8.2.8
92function MathExp(x) {
93  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
94  return %Math_exp(x);
95}
96
97// ECMA 262 - 15.8.2.9
98function MathFloor(x) {
99  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
100  // It's more common to call this with a positive number that's out
101  // of range than negative numbers; check the upper bound first.
102  if (x < 0x80000000 && x > 0) {
103    // Numbers in the range [0, 2^31) can be floored by converting
104    // them to an unsigned 32-bit value using the shift operator.
105    // We avoid doing so for -0, because the result of Math.floor(-0)
106    // has to be -0, which wouldn't be the case with the shift.
107    return TO_UINT32(x);
108  } else {
109    return %Math_floor(x);
110  }
111}
112
113// ECMA 262 - 15.8.2.10
114function MathLog(x) {
115  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
116  return %_MathLog(x);
117}
118
119// ECMA 262 - 15.8.2.11
120function MathMax(arg1, arg2) {  // length == 2
121  var length = %_ArgumentsLength();
122  if (length == 0) {
123    return -1/0;  // Compiler constant-folds this to -Infinity.
124  }
125  var r = arg1;
126  if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
127  if (NUMBER_IS_NAN(r)) return r;
128  for (var i = 1; i < length; i++) {
129    var n = %_Arguments(i);
130    if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
131    if (NUMBER_IS_NAN(n)) return n;
132    // Make sure +0 is considered greater than -0.  -0 is never a Smi, +0 can be
133    // a Smi or heap number.
134    if (n > r || (r === 0 && n === 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
135  }
136  return r;
137}
138
139// ECMA 262 - 15.8.2.12
140function MathMin(arg1, arg2) {  // length == 2
141  var length = %_ArgumentsLength();
142  if (length == 0) {
143    return 1/0;  // Compiler constant-folds this to Infinity.
144  }
145  var r = arg1;
146  if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
147  if (NUMBER_IS_NAN(r)) return r;
148  for (var i = 1; i < length; i++) {
149    var n = %_Arguments(i);
150    if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
151    if (NUMBER_IS_NAN(n)) return n;
152    // Make sure -0 is considered less than +0.  -0 is never a Smi, +0 can b a
153    // Smi or a heap number.
154    if (n < r || (r === 0 && n === 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
155  }
156  return r;
157}
158
159// ECMA 262 - 15.8.2.13
160function MathPow(x, y) {
161  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
162  if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
163  return %_MathPow(x, y);
164}
165
166// ECMA 262 - 15.8.2.14
167function MathRandom() {
168  return %_RandomHeapNumber();
169}
170
171// ECMA 262 - 15.8.2.15
172function MathRound(x) {
173  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
174  return %RoundNumber(x);
175}
176
177// ECMA 262 - 15.8.2.16
178function MathSin(x) {
179  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
180  return %_MathSin(x);
181}
182
183// ECMA 262 - 15.8.2.17
184function MathSqrt(x) {
185  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
186  return %_MathSqrt(x);
187}
188
189// ECMA 262 - 15.8.2.18
190function MathTan(x) {
191  if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
192  return %Math_tan(x);
193}
194
195
196// -------------------------------------------------------------------
197
198function SetupMath() {
199  // Setup math constants.
200  // ECMA-262, section 15.8.1.1.
201  %OptimizeObjectForAddingMultipleProperties($Math, 8);
202  %SetProperty($Math,
203               "E",
204               2.7182818284590452354,
205               DONT_ENUM |  DONT_DELETE | READ_ONLY);
206  // ECMA-262, section 15.8.1.2.
207  %SetProperty($Math,
208               "LN10",
209               2.302585092994046,
210               DONT_ENUM |  DONT_DELETE | READ_ONLY);
211  // ECMA-262, section 15.8.1.3.
212  %SetProperty($Math,
213               "LN2",
214               0.6931471805599453,
215               DONT_ENUM |  DONT_DELETE | READ_ONLY);
216  // ECMA-262, section 15.8.1.4.
217  %SetProperty($Math,
218               "LOG2E",
219               1.4426950408889634,
220               DONT_ENUM |  DONT_DELETE | READ_ONLY);
221  %SetProperty($Math,
222               "LOG10E",
223               0.4342944819032518,
224               DONT_ENUM |  DONT_DELETE | READ_ONLY);
225  %SetProperty($Math,
226               "PI",
227               3.1415926535897932,
228               DONT_ENUM |  DONT_DELETE | READ_ONLY);
229  %SetProperty($Math,
230               "SQRT1_2",
231               0.7071067811865476,
232               DONT_ENUM |  DONT_DELETE | READ_ONLY);
233  %SetProperty($Math,
234               "SQRT2",
235               1.4142135623730951,
236               DONT_ENUM |  DONT_DELETE | READ_ONLY);
237  %ToFastProperties($Math);
238
239  // Setup non-enumerable functions of the Math object and
240  // set their names.
241  InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array(
242    "random", MathRandom,
243    "abs", MathAbs,
244    "acos", MathAcos,
245    "asin", MathAsin,
246    "atan", MathAtan,
247    "ceil", MathCeil,
248    "cos", MathCos,
249    "exp", MathExp,
250    "floor", MathFloor,
251    "log", MathLog,
252    "round", MathRound,
253    "sin", MathSin,
254    "sqrt", MathSqrt,
255    "tan", MathTan,
256    "atan2", MathAtan2,
257    "pow", MathPow,
258    "max", MathMax,
259    "min", MathMin
260  ));
261};
262
263
264SetupMath();
265