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 = ToNumber(x); 48 return %Math_abs(x); 49} 50 51// ECMA 262 - 15.8.2.2 52function MathAcos(x) { 53 if (!IS_NUMBER(x)) x = ToNumber(x); 54 return %Math_acos(x); 55} 56 57// ECMA 262 - 15.8.2.3 58function MathAsin(x) { 59 if (!IS_NUMBER(x)) x = ToNumber(x); 60 return %Math_asin(x); 61} 62 63// ECMA 262 - 15.8.2.4 64function MathAtan(x) { 65 if (!IS_NUMBER(x)) x = ToNumber(x); 66 return %Math_atan(x); 67} 68 69// ECMA 262 - 15.8.2.5 70// The naming of y and x matches the spec, as does the order in which 71// ToNumber (valueOf) is called. 72function MathAtan2(y, x) { 73 if (!IS_NUMBER(y)) y = ToNumber(y); 74 if (!IS_NUMBER(x)) x = ToNumber(x); 75 return %Math_atan2(y, x); 76} 77 78// ECMA 262 - 15.8.2.6 79function MathCeil(x) { 80 if (!IS_NUMBER(x)) x = ToNumber(x); 81 return %Math_ceil(x); 82} 83 84// ECMA 262 - 15.8.2.7 85function MathCos(x) { 86 if (!IS_NUMBER(x)) x = ToNumber(x); 87 return %_Math_cos(x); 88} 89 90// ECMA 262 - 15.8.2.8 91function MathExp(x) { 92 if (!IS_NUMBER(x)) x = ToNumber(x); 93 return %Math_exp(x); 94} 95 96// ECMA 262 - 15.8.2.9 97function MathFloor(x) { 98 if (!IS_NUMBER(x)) x = ToNumber(x); 99 // 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. 101 if (x < 0x80000000 && x > 0) { 102 // 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. 106 return TO_UINT32(x); 107 } else { 108 return %Math_floor(x); 109 } 110} 111 112// ECMA 262 - 15.8.2.10 113function MathLog(x) { 114 if (!IS_NUMBER(x)) x = ToNumber(x); 115 return %Math_log(x); 116} 117 118// ECMA 262 - 15.8.2.11 119function MathMax(arg1, arg2) { // length == 2 120 var length = %_ArgumentsLength(); 121 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); 130 if (NUMBER_IS_NAN(n)) return n; 131 // 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; 134 } 135 return r; 136} 137 138// ECMA 262 - 15.8.2.12 139function MathMin(arg1, arg2) { // length == 2 140 var length = %_ArgumentsLength(); 141 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); 150 if (NUMBER_IS_NAN(n)) return n; 151 // 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; 154 } 155 return r; 156} 157 158// ECMA 262 - 15.8.2.13 159function 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} 164 165// ECMA 262 - 15.8.2.14 166function MathRandom() { 167 return %_RandomPositiveSmi() / 0x40000000; 168} 169 170// ECMA 262 - 15.8.2.15 171function MathRound(x) { 172 if (!IS_NUMBER(x)) x = ToNumber(x); 173 return %Math_round(x); 174} 175 176// ECMA 262 - 15.8.2.16 177function MathSin(x) { 178 if (!IS_NUMBER(x)) x = ToNumber(x); 179 return %_Math_sin(x); 180} 181 182// ECMA 262 - 15.8.2.17 183function MathSqrt(x) { 184 if (!IS_NUMBER(x)) x = ToNumber(x); 185 return %Math_sqrt(x); 186} 187 188// ECMA 262 - 15.8.2.18 189function MathTan(x) { 190 if (!IS_NUMBER(x)) x = ToNumber(x); 191 return %Math_tan(x); 192} 193 194 195// ------------------------------------------------------------------- 196 197function SetupMath() { 198 // Setup math constants. 199 // ECMA-262, section 15.8.1.1. 200 %OptimizeObjectForAddingMultipleProperties($Math, 8); 201 %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); 236 %ToFastProperties($Math); 237 238 // Setup non-enumerable functions of the Math object and 239 // set their names. 240 InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array( 241 "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}; 261 262 263SetupMath(); 264