blob: 70b8c57cae5c48058c14ce76fdf756f2aabb3739 [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;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000047 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +000048 if (x === 0) return 0; // To handle -0.
49 return x > 0 ? x : -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) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000054 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000055 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) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000060 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000061 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) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000066 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000067 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
kasperl@chromium.org68ac0092009-07-09 06:00:35 +000071// The naming of y and x matches the spec, as does the order in which
72// ToNumber (valueOf) is called.
73function MathAtan2(y, x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000074 if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
75 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
kasperl@chromium.org68ac0092009-07-09 06:00:35 +000076 return %Math_atan2(y, x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000077}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000079// ECMA 262 - 15.8.2.6
ager@chromium.orgeadaf222009-06-16 09:43:10 +000080function MathCeil(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000081 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000082 return %Math_ceil(x);
83}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000085// ECMA 262 - 15.8.2.7
ager@chromium.orgeadaf222009-06-16 09:43:10 +000086function MathCos(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000087 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +000088 return %_MathCos(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000089}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000090
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000091// ECMA 262 - 15.8.2.8
ager@chromium.orgeadaf222009-06-16 09:43:10 +000092function MathExp(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000093 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +000094 return %Math_exp(x);
95}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000096
kasperl@chromium.org41044eb2008-10-06 08:24:46 +000097// ECMA 262 - 15.8.2.9
ager@chromium.orgeadaf222009-06-16 09:43:10 +000098function MathFloor(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000099 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +0000100 // 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.
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000102 if (x < 0x80000000 && x > 0) {
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000103 // 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.
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000107 return TO_UINT32(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000108 } else {
109 return %Math_floor(x);
110 }
111}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000113// ECMA 262 - 15.8.2.10
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000114function MathLog(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000115 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000116 return %_MathLog(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000117}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000118
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000119// ECMA 262 - 15.8.2.11
120function MathMax(arg1, arg2) { // length == 2
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000121 var length = %_ArgumentsLength();
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000122 if (length == 0) {
123 return -1/0; // Compiler constant-folds this to -Infinity.
124 }
125 var r = arg1;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000126 if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000127 if (NUMBER_IS_NAN(r)) return r;
128 for (var i = 1; i < length; i++) {
129 var n = %_Arguments(i);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000130 if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000131 if (NUMBER_IS_NAN(n)) return n;
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000132 // 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;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135 }
136 return r;
137}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000138
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000139// ECMA 262 - 15.8.2.12
140function MathMin(arg1, arg2) { // length == 2
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000141 var length = %_ArgumentsLength();
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000142 if (length == 0) {
143 return 1/0; // Compiler constant-folds this to Infinity.
144 }
145 var r = arg1;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000146 if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000147 if (NUMBER_IS_NAN(r)) return r;
148 for (var i = 1; i < length; i++) {
149 var n = %_Arguments(i);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000150 if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000151 if (NUMBER_IS_NAN(n)) return n;
kmillikin@chromium.org13bd2942009-12-16 15:36:05 +0000152 // 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;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155 }
156 return r;
157}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000158
159// ECMA 262 - 15.8.2.13
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000160function MathPow(x, y) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000161 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
162 if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000163 return %_MathPow(x, y);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000164}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000165
166// ECMA 262 - 15.8.2.14
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000167function MathRandom() {
ager@chromium.org357bf652010-04-12 11:30:10 +0000168 return %_RandomHeapNumber();
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000169}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000170
171// ECMA 262 - 15.8.2.15
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000172function MathRound(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000173 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
whesse@chromium.orgcec079d2010-03-22 14:44:04 +0000174 return %RoundNumber(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000175}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000176
177// ECMA 262 - 15.8.2.16
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000178function MathSin(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000179 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000180 return %_MathSin(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000181}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000182
183// ECMA 262 - 15.8.2.17
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000184function MathSqrt(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000185 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000186 return %_MathSqrt(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000187}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000188
189// ECMA 262 - 15.8.2.18
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000190function MathTan(x) {
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000191 if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000192 return %Math_tan(x);
193}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000194
195
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000196// -------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000197
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000198function SetupMath() {
199 // Setup math constants.
200 // ECMA-262, section 15.8.1.1.
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000201 %OptimizeObjectForAddingMultipleProperties($Math, 8);
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000202 %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",
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +0000223 0.4342944819032518,
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000224 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);
ager@chromium.org5c838252010-02-19 08:53:10 +0000237 %ToFastProperties($Math);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000238
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000239 // Setup non-enumerable functions of the Math object and
240 // set their names.
ager@chromium.org9085a012009-05-11 19:22:57 +0000241 InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array(
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000242 "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};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000262
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000263
264SetupMath();