blob: 1f5ce87af93f8672fa9c6af0cb5cc274a67a8679 [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);
98 if (0 < x && x <= 0x7FFFFFFF) {
99 // Numbers in the range [0, 2^31) can be floored by converting
100 // them to an unsigned 32-bit value using the shift operator.
101 // We avoid doing so for -0, because the result of Math.floor(-0)
102 // has to be -0, which wouldn't be the case with the shift.
103 return x << 0;
104 } else {
105 return %Math_floor(x);
106 }
107}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000108
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000109// ECMA 262 - 15.8.2.10
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000110function MathLog(x) {
111 if (!IS_NUMBER(x)) x = ToNumber(x);
112 return %Math_log(x);
113}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000115// ECMA 262 - 15.8.2.11
116function MathMax(arg1, arg2) { // length == 2
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000117 var r = -$Infinity;
118 for (var i = %_ArgumentsLength() - 1; i >= 0; --i) {
119 var n = ToNumber(%_Arguments(i));
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000120 if (NUMBER_IS_NAN(n)) return n;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000121 // Make sure +0 is consider greater than -0.
122 if (n > r || (n === 0 && r === 0 && (1 / n) > (1 / r))) r = n;
123 }
124 return r;
125}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000126
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000127// ECMA 262 - 15.8.2.12
128function MathMin(arg1, arg2) { // length == 2
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000129 var r = $Infinity;
130 for (var i = %_ArgumentsLength() - 1; i >= 0; --i) {
131 var n = ToNumber(%_Arguments(i));
mads.s.ager@gmail.com769cc962008-08-06 10:02:49 +0000132 if (NUMBER_IS_NAN(n)) return n;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000133 // Make sure -0 is consider less than +0.
134 if (n < r || (n === 0 && r === 0 && (1 / n) < (1 / r))) r = n;
135 }
136 return r;
137}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000138
139// ECMA 262 - 15.8.2.13
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000140function MathPow(x, y) {
141 if (!IS_NUMBER(x)) x = ToNumber(x);
142 if (!IS_NUMBER(y)) y = ToNumber(y);
143 return %Math_pow(x, y);
144}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000145
146// ECMA 262 - 15.8.2.14
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000147function MathRandom() {
148 return %_RandomPositiveSmi() / 0x40000000;
149}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000150
151// ECMA 262 - 15.8.2.15
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000152function MathRound(x) {
153 if (!IS_NUMBER(x)) x = ToNumber(x);
154 return %Math_round(x);
155}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000156
157// ECMA 262 - 15.8.2.16
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000158function MathSin(x) {
159 if (!IS_NUMBER(x)) x = ToNumber(x);
160 return %_Math_sin(x);
161}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000162
163// ECMA 262 - 15.8.2.17
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000164function MathSqrt(x) {
165 if (!IS_NUMBER(x)) x = ToNumber(x);
166 return %Math_sqrt(x);
167}
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000168
169// ECMA 262 - 15.8.2.18
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000170function MathTan(x) {
171 if (!IS_NUMBER(x)) x = ToNumber(x);
172 return %Math_tan(x);
173}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000174
175
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000176// -------------------------------------------------------------------
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000177
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000178function SetupMath() {
179 // Setup math constants.
180 // ECMA-262, section 15.8.1.1.
181 %SetProperty($Math,
182 "E",
183 2.7182818284590452354,
184 DONT_ENUM | DONT_DELETE | READ_ONLY);
185 // ECMA-262, section 15.8.1.2.
186 %SetProperty($Math,
187 "LN10",
188 2.302585092994046,
189 DONT_ENUM | DONT_DELETE | READ_ONLY);
190 // ECMA-262, section 15.8.1.3.
191 %SetProperty($Math,
192 "LN2",
193 0.6931471805599453,
194 DONT_ENUM | DONT_DELETE | READ_ONLY);
195 // ECMA-262, section 15.8.1.4.
196 %SetProperty($Math,
197 "LOG2E",
198 1.4426950408889634,
199 DONT_ENUM | DONT_DELETE | READ_ONLY);
200 %SetProperty($Math,
201 "LOG10E",
202 0.43429448190325176,
203 DONT_ENUM | DONT_DELETE | READ_ONLY);
204 %SetProperty($Math,
205 "PI",
206 3.1415926535897932,
207 DONT_ENUM | DONT_DELETE | READ_ONLY);
208 %SetProperty($Math,
209 "SQRT1_2",
210 0.7071067811865476,
211 DONT_ENUM | DONT_DELETE | READ_ONLY);
212 %SetProperty($Math,
213 "SQRT2",
214 1.4142135623730951,
215 DONT_ENUM | DONT_DELETE | READ_ONLY);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000216
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000217 // Setup non-enumerable functions of the Math object and
218 // set their names.
ager@chromium.org9085a012009-05-11 19:22:57 +0000219 InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array(
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000220 "random", MathRandom,
221 "abs", MathAbs,
222 "acos", MathAcos,
223 "asin", MathAsin,
224 "atan", MathAtan,
225 "ceil", MathCeil,
226 "cos", MathCos,
227 "exp", MathExp,
228 "floor", MathFloor,
229 "log", MathLog,
230 "round", MathRound,
231 "sin", MathSin,
232 "sqrt", MathSqrt,
233 "tan", MathTan,
234 "atan2", MathAtan2,
235 "pow", MathPow,
236 "max", MathMax,
237 "min", MathMin
238 ));
239};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000240
kasperl@chromium.org41044eb2008-10-06 08:24:46 +0000241
242SetupMath();