blob: d804648f54aef4a9dfe228da13cedc1e214ae142 [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.
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000032const $floor = MathFloor;
33const $random = MathRandom;
34const $abs = MathAbs;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000035
36// Instance class name can only be set on functions. That is the only
37// purpose for MathConstructor.
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000038function MathConstructor() {}
39%FunctionSetInstanceClassName(MathConstructor, 'Math');
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040const $Math = new MathConstructor();
41$Math.__proto__ = global.Object.prototype;
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000042%SetProperty(global, "Math", $Math, DONT_ENUM);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000044// ECMA 262 - 15.8.2.1
45function MathAbs(x) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +000046 if (%_IsSmi(x)) return x >= 0 ? x : -x;
47 if (!IS_NUMBER(x)) x = ToNumber(x);
48 return %Math_abs(x);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +000049}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000050
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000051// ECMA 262 - 15.8.2.2
ager@chromium.orgeadaf222009-06-16 09:43:10 +000052function MathAcos(x) {
53 if (!IS_NUMBER(x)) x = ToNumber(x);
54 return %Math_acos(x);
55}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000056
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000057// ECMA 262 - 15.8.2.3
ager@chromium.orgeadaf222009-06-16 09:43:10 +000058function MathAsin(x) {
59 if (!IS_NUMBER(x)) x = ToNumber(x);
60 return %Math_asin(x);
61}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000062
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000063// ECMA 262 - 15.8.2.4
ager@chromium.orgeadaf222009-06-16 09:43:10 +000064function MathAtan(x) {
65 if (!IS_NUMBER(x)) x = ToNumber(x);
66 return %Math_atan(x);
67}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000068
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000069// ECMA 262 - 15.8.2.5
kasperl@chromium.org68ac0092009-07-09 06:00:35 +000070// The naming of y and x matches the spec, as does the order in which
71// ToNumber (valueOf) is called.
72function MathAtan2(y, x) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +000073 if (!IS_NUMBER(y)) y = ToNumber(y);
kasperl@chromium.org68ac0092009-07-09 06:00:35 +000074 if (!IS_NUMBER(x)) x = ToNumber(x);
75 return %Math_atan2(y, x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000076}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000078// ECMA 262 - 15.8.2.6
ager@chromium.orgeadaf222009-06-16 09:43:10 +000079function MathCeil(x) {
80 if (!IS_NUMBER(x)) x = ToNumber(x);
81 return %Math_ceil(x);
82}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000083
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000084// ECMA 262 - 15.8.2.7
ager@chromium.orgeadaf222009-06-16 09:43:10 +000085function MathCos(x) {
86 if (!IS_NUMBER(x)) x = ToNumber(x);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +000087 return %Math_cos(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000088}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000089
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000090// ECMA 262 - 15.8.2.8
ager@chromium.orgeadaf222009-06-16 09:43:10 +000091function MathExp(x) {
92 if (!IS_NUMBER(x)) x = ToNumber(x);
93 return %Math_exp(x);
94}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000095
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000096// ECMA 262 - 15.8.2.9
ager@chromium.orgeadaf222009-06-16 09:43:10 +000097function MathFloor(x) {
98 if (!IS_NUMBER(x)) x = ToNumber(x);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +000099 // 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.
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000101 if (x < 0x80000000 && x > 0) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000102 // 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.
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000106 return TO_UINT32(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000107 } else {
108 return %Math_floor(x);
109 }
110}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000111
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000112// ECMA 262 - 15.8.2.10
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000113function MathLog(x) {
114 if (!IS_NUMBER(x)) x = ToNumber(x);
115 return %Math_log(x);
116}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000117
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000118// ECMA 262 - 15.8.2.11
119function MathMax(arg1, arg2) { // length == 2
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000120 var length = %_ArgumentsLength();
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000121 if (length == 0) {
122 return -1/0; // Compiler constant-folds this to -Infinity.
123 }
124 var r = arg1;
125 if (!IS_NUMBER(r)) r = ToNumber(r);
126 if (NUMBER_IS_NAN(r)) return r;
127 for (var i = 1; i < length; i++) {
128 var n = %_Arguments(i);
129 if (!IS_NUMBER(n)) n = ToNumber(n);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000130 if (NUMBER_IS_NAN(n)) return n;
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000131 // Make sure +0 is considered greater than -0. -0 is never a Smi, +0 can be
132 // a Smi or heap number.
133 if (n > r || (r === 0 && n === 0 && !%_IsSmi(r) && 1 / r < 0)) r = n;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000134 }
135 return r;
136}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000137
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000138// ECMA 262 - 15.8.2.12
139function MathMin(arg1, arg2) { // length == 2
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000140 var length = %_ArgumentsLength();
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000141 if (length == 0) {
142 return 1/0; // Compiler constant-folds this to Infinity.
143 }
144 var r = arg1;
145 if (!IS_NUMBER(r)) r = ToNumber(r);
146 if (NUMBER_IS_NAN(r)) return r;
147 for (var i = 1; i < length; i++) {
148 var n = %_Arguments(i);
149 if (!IS_NUMBER(n)) n = ToNumber(n);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000150 if (NUMBER_IS_NAN(n)) return n;
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000151 // Make sure -0 is considered less than +0. -0 is never a Smi, +0 can b a
152 // Smi or a heap number.
153 if (n < r || (r === 0 && n === 0 && !%_IsSmi(n) && 1 / n < 0)) r = n;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000154 }
155 return r;
156}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000157
158// ECMA 262 - 15.8.2.13
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000159function MathPow(x, y) {
160 if (!IS_NUMBER(x)) x = ToNumber(x);
161 if (!IS_NUMBER(y)) y = ToNumber(y);
162 return %Math_pow(x, y);
163}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000164
165// ECMA 262 - 15.8.2.14
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000166function MathRandom() {
167 return %_RandomPositiveSmi() / 0x40000000;
168}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000169
170// ECMA 262 - 15.8.2.15
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000171function MathRound(x) {
172 if (!IS_NUMBER(x)) x = ToNumber(x);
173 return %Math_round(x);
174}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000175
176// ECMA 262 - 15.8.2.16
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000177function MathSin(x) {
178 if (!IS_NUMBER(x)) x = ToNumber(x);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000179 return %Math_sin(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000180}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000181
182// ECMA 262 - 15.8.2.17
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000183function MathSqrt(x) {
184 if (!IS_NUMBER(x)) x = ToNumber(x);
185 return %Math_sqrt(x);
186}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000187
188// ECMA 262 - 15.8.2.18
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000189function MathTan(x) {
190 if (!IS_NUMBER(x)) x = ToNumber(x);
191 return %Math_tan(x);
192}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193
194
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000195// -------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000197function SetupMath() {
198 // Setup math constants.
199 // ECMA-262, section 15.8.1.1.
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000200 %OptimizeObjectForAddingMultipleProperties($Math, 8);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000201 %SetProperty($Math,
202 "E",
203 2.7182818284590452354,
204 DONT_ENUM | DONT_DELETE | READ_ONLY);
205 // ECMA-262, section 15.8.1.2.
206 %SetProperty($Math,
207 "LN10",
208 2.302585092994046,
209 DONT_ENUM | DONT_DELETE | READ_ONLY);
210 // ECMA-262, section 15.8.1.3.
211 %SetProperty($Math,
212 "LN2",
213 0.6931471805599453,
214 DONT_ENUM | DONT_DELETE | READ_ONLY);
215 // ECMA-262, section 15.8.1.4.
216 %SetProperty($Math,
217 "LOG2E",
218 1.4426950408889634,
219 DONT_ENUM | DONT_DELETE | READ_ONLY);
220 %SetProperty($Math,
221 "LOG10E",
222 0.43429448190325176,
223 DONT_ENUM | DONT_DELETE | READ_ONLY);
224 %SetProperty($Math,
225 "PI",
226 3.1415926535897932,
227 DONT_ENUM | DONT_DELETE | READ_ONLY);
228 %SetProperty($Math,
229 "SQRT1_2",
230 0.7071067811865476,
231 DONT_ENUM | DONT_DELETE | READ_ONLY);
232 %SetProperty($Math,
233 "SQRT2",
234 1.4142135623730951,
235 DONT_ENUM | DONT_DELETE | READ_ONLY);
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000236 %TransformToFastProperties($Math);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000238 // Setup non-enumerable functions of the Math object and
239 // set their names.
ager@chromium.org9085a012009-05-11 19:22:57 +0000240 InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array(
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000241 "random", MathRandom,
242 "abs", MathAbs,
243 "acos", MathAcos,
244 "asin", MathAsin,
245 "atan", MathAtan,
246 "ceil", MathCeil,
247 "cos", MathCos,
248 "exp", MathExp,
249 "floor", MathFloor,
250 "log", MathLog,
251 "round", MathRound,
252 "sin", MathSin,
253 "sqrt", MathSqrt,
254 "tan", MathTan,
255 "atan2", MathAtan2,
256 "pow", MathPow,
257 "max", MathMax,
258 "min", MathMin
259 ));
260};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000261
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000262
263SetupMath();