blob: d12927e74a06b89970b71a9582671a4fd986d2a6 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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 $Infinity = global.Infinity;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000033const $floor = MathFloor;
34const $random = MathRandom;
35const $abs = MathAbs;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036
37// Instance class name can only be set on functions. That is the only
38// purpose for MathConstructor.
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000039function MathConstructor() {}
40%FunctionSetInstanceClassName(MathConstructor, 'Math');
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000041const $Math = new MathConstructor();
42$Math.__proto__ = global.Object.prototype;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000043%SetProperty(global, "Math", $Math, DONT_ENUM);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000045// ECMA 262 - 15.8.2.1
46function MathAbs(x) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +000047 if (%_IsSmi(x)) return x >= 0 ? x : -x;
48 if (!IS_NUMBER(x)) x = ToNumber(x);
49 return %Math_abs(x);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +000050}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000051
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000052// ECMA 262 - 15.8.2.2
ager@chromium.orgeadaf222009-06-16 09:43:10 +000053function MathAcos(x) {
54 if (!IS_NUMBER(x)) x = ToNumber(x);
55 return %Math_acos(x);
56}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000057
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000058// ECMA 262 - 15.8.2.3
ager@chromium.orgeadaf222009-06-16 09:43:10 +000059function MathAsin(x) {
60 if (!IS_NUMBER(x)) x = ToNumber(x);
61 return %Math_asin(x);
62}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000064// ECMA 262 - 15.8.2.4
ager@chromium.orgeadaf222009-06-16 09:43:10 +000065function MathAtan(x) {
66 if (!IS_NUMBER(x)) x = ToNumber(x);
67 return %Math_atan(x);
68}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000069
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000070// ECMA 262 - 15.8.2.5
ager@chromium.orgeadaf222009-06-16 09:43:10 +000071function MathAtan2(x, y) {
72 if (!IS_NUMBER(x)) x = ToNumber(x);
73 if (!IS_NUMBER(y)) y = ToNumber(y);
74 return %Math_atan2(x, y);
75}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000076
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000077// ECMA 262 - 15.8.2.6
ager@chromium.orgeadaf222009-06-16 09:43:10 +000078function MathCeil(x) {
79 if (!IS_NUMBER(x)) x = ToNumber(x);
80 return %Math_ceil(x);
81}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000082
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000083// ECMA 262 - 15.8.2.7
ager@chromium.orgeadaf222009-06-16 09:43:10 +000084function MathCos(x) {
85 if (!IS_NUMBER(x)) x = ToNumber(x);
86 return %_Math_cos(x);
87}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000088
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000089// ECMA 262 - 15.8.2.8
ager@chromium.orgeadaf222009-06-16 09:43:10 +000090function MathExp(x) {
91 if (!IS_NUMBER(x)) x = ToNumber(x);
92 return %Math_exp(x);
93}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000095// ECMA 262 - 15.8.2.9
ager@chromium.orgeadaf222009-06-16 09:43:10 +000096function MathFloor(x) {
97 if (!IS_NUMBER(x)) x = ToNumber(x);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +000098 // It's more common to call this with a positive number that's out
99 // of range than negative numbers; check the upper bound first.
100 if (x <= 0x7FFFFFFF && x > 0) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000101 // Numbers in the range [0, 2^31) can be floored by converting
102 // them to an unsigned 32-bit value using the shift operator.
103 // We avoid doing so for -0, because the result of Math.floor(-0)
104 // has to be -0, which wouldn't be the case with the shift.
105 return x << 0;
106 } else {
107 return %Math_floor(x);
108 }
109}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000110
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000111// ECMA 262 - 15.8.2.10
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000112function MathLog(x) {
113 if (!IS_NUMBER(x)) x = ToNumber(x);
114 return %Math_log(x);
115}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000116
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000117// ECMA 262 - 15.8.2.11
118function MathMax(arg1, arg2) { // length == 2
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000119 var r = -$Infinity;
120 for (var i = %_ArgumentsLength() - 1; i >= 0; --i) {
121 var n = ToNumber(%_Arguments(i));
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000122 if (NUMBER_IS_NAN(n)) return n;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123 // Make sure +0 is consider greater than -0.
124 if (n > r || (n === 0 && r === 0 && (1 / n) > (1 / r))) r = n;
125 }
126 return r;
127}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000129// ECMA 262 - 15.8.2.12
130function MathMin(arg1, arg2) { // length == 2
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000131 var r = $Infinity;
132 for (var i = %_ArgumentsLength() - 1; i >= 0; --i) {
133 var n = ToNumber(%_Arguments(i));
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000134 if (NUMBER_IS_NAN(n)) return n;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135 // Make sure -0 is consider less than +0.
136 if (n < r || (n === 0 && r === 0 && (1 / n) < (1 / r))) r = n;
137 }
138 return r;
139}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000140
141// ECMA 262 - 15.8.2.13
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000142function MathPow(x, y) {
143 if (!IS_NUMBER(x)) x = ToNumber(x);
144 if (!IS_NUMBER(y)) y = ToNumber(y);
145 return %Math_pow(x, y);
146}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000147
148// ECMA 262 - 15.8.2.14
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000149function MathRandom() {
150 return %_RandomPositiveSmi() / 0x40000000;
151}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000152
153// ECMA 262 - 15.8.2.15
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000154function MathRound(x) {
155 if (!IS_NUMBER(x)) x = ToNumber(x);
156 return %Math_round(x);
157}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000158
159// ECMA 262 - 15.8.2.16
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000160function MathSin(x) {
161 if (!IS_NUMBER(x)) x = ToNumber(x);
162 return %_Math_sin(x);
163}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000164
165// ECMA 262 - 15.8.2.17
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000166function MathSqrt(x) {
167 if (!IS_NUMBER(x)) x = ToNumber(x);
168 return %Math_sqrt(x);
169}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000170
171// ECMA 262 - 15.8.2.18
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000172function MathTan(x) {
173 if (!IS_NUMBER(x)) x = ToNumber(x);
174 return %Math_tan(x);
175}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176
177
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000178// -------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000179
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000180function SetupMath() {
181 // Setup math constants.
182 // ECMA-262, section 15.8.1.1.
183 %SetProperty($Math,
184 "E",
185 2.7182818284590452354,
186 DONT_ENUM | DONT_DELETE | READ_ONLY);
187 // ECMA-262, section 15.8.1.2.
188 %SetProperty($Math,
189 "LN10",
190 2.302585092994046,
191 DONT_ENUM | DONT_DELETE | READ_ONLY);
192 // ECMA-262, section 15.8.1.3.
193 %SetProperty($Math,
194 "LN2",
195 0.6931471805599453,
196 DONT_ENUM | DONT_DELETE | READ_ONLY);
197 // ECMA-262, section 15.8.1.4.
198 %SetProperty($Math,
199 "LOG2E",
200 1.4426950408889634,
201 DONT_ENUM | DONT_DELETE | READ_ONLY);
202 %SetProperty($Math,
203 "LOG10E",
204 0.43429448190325176,
205 DONT_ENUM | DONT_DELETE | READ_ONLY);
206 %SetProperty($Math,
207 "PI",
208 3.1415926535897932,
209 DONT_ENUM | DONT_DELETE | READ_ONLY);
210 %SetProperty($Math,
211 "SQRT1_2",
212 0.7071067811865476,
213 DONT_ENUM | DONT_DELETE | READ_ONLY);
214 %SetProperty($Math,
215 "SQRT2",
216 1.4142135623730951,
217 DONT_ENUM | DONT_DELETE | READ_ONLY);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000218
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000219 // Setup non-enumerable functions of the Math object and
220 // set their names.
ager@chromium.org9085a012009-05-11 19:22:57 +0000221 InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array(
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000222 "random", MathRandom,
223 "abs", MathAbs,
224 "acos", MathAcos,
225 "asin", MathAsin,
226 "atan", MathAtan,
227 "ceil", MathCeil,
228 "cos", MathCos,
229 "exp", MathExp,
230 "floor", MathFloor,
231 "log", MathLog,
232 "round", MathRound,
233 "sin", MathSin,
234 "sqrt", MathSqrt,
235 "tan", MathTan,
236 "atan2", MathAtan2,
237 "pow", MathPow,
238 "max", MathMax,
239 "min", MathMin
240 ));
241};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000243
244SetupMath();