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 $Infinity = global.Infinity; 33const $floor = MathFloor; 34const $random = MathRandom; 35const $abs = MathAbs; 36 37// Instance class name can only be set on functions. That is the only 38// purpose for MathConstructor. 39function MathConstructor() {} 40%FunctionSetInstanceClassName(MathConstructor, 'Math'); 41const $Math = new MathConstructor(); 42$Math.__proto__ = global.Object.prototype; 43%SetProperty(global, "Math", $Math, DONT_ENUM); 44 45// ECMA 262 - 15.8.2.1 46function MathAbs(x) { 47 if (%_IsSmi(x)) return x >= 0 ? x : -x; 48 if (!IS_NUMBER(x)) x = ToNumber(x); 49 return %Math_abs(x); 50} 51 52// ECMA 262 - 15.8.2.2 53function MathAcos(x) { 54 if (!IS_NUMBER(x)) x = ToNumber(x); 55 return %Math_acos(x); 56} 57 58// ECMA 262 - 15.8.2.3 59function MathAsin(x) { 60 if (!IS_NUMBER(x)) x = ToNumber(x); 61 return %Math_asin(x); 62} 63 64// ECMA 262 - 15.8.2.4 65function MathAtan(x) { 66 if (!IS_NUMBER(x)) x = ToNumber(x); 67 return %Math_atan(x); 68} 69 70// ECMA 262 - 15.8.2.5 71// The naming of y and x matches the spec, as does the order in which 72// ToNumber (valueOf) is called. 73function MathAtan2(y, x) { 74 if (!IS_NUMBER(y)) y = ToNumber(y); 75 if (!IS_NUMBER(x)) x = ToNumber(x); 76 return %Math_atan2(y, x); 77} 78 79// ECMA 262 - 15.8.2.6 80function MathCeil(x) { 81 if (!IS_NUMBER(x)) x = ToNumber(x); 82 return %Math_ceil(x); 83} 84 85// ECMA 262 - 15.8.2.7 86function MathCos(x) { 87 if (!IS_NUMBER(x)) x = ToNumber(x); 88 return %_Math_cos(x); 89} 90 91// ECMA 262 - 15.8.2.8 92function MathExp(x) { 93 if (!IS_NUMBER(x)) x = ToNumber(x); 94 return %Math_exp(x); 95} 96 97// ECMA 262 - 15.8.2.9 98function MathFloor(x) { 99 if (!IS_NUMBER(x)) x = ToNumber(x); 100 // 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. 102 if (x <= 0x7FFFFFFF && x > 0) { 103 // 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. 107 return x << 0; 108 } else { 109 return %Math_floor(x); 110 } 111} 112 113// ECMA 262 - 15.8.2.10 114function MathLog(x) { 115 if (!IS_NUMBER(x)) x = ToNumber(x); 116 return %Math_log(x); 117} 118 119// ECMA 262 - 15.8.2.11 120function MathMax(arg1, arg2) { // length == 2 121 var r = -$Infinity; 122 var length = %_ArgumentsLength(); 123 for (var i = 0; i < length; i++) { 124 var n = ToNumber(%_Arguments(i)); 125 if (NUMBER_IS_NAN(n)) return n; 126 // Make sure +0 is considered greater than -0. 127 if (n > r || (r === 0 && n === 0 && !%_IsSmi(r))) r = n; 128 } 129 return r; 130} 131 132// ECMA 262 - 15.8.2.12 133function MathMin(arg1, arg2) { // length == 2 134 var r = $Infinity; 135 var length = %_ArgumentsLength(); 136 for (var i = 0; i < length; i++) { 137 var n = ToNumber(%_Arguments(i)); 138 if (NUMBER_IS_NAN(n)) return n; 139 // Make sure -0 is considered less than +0. 140 if (n < r || (r === 0 && n === 0 && !%_IsSmi(n))) r = n; 141 } 142 return r; 143} 144 145// ECMA 262 - 15.8.2.13 146function MathPow(x, y) { 147 if (!IS_NUMBER(x)) x = ToNumber(x); 148 if (!IS_NUMBER(y)) y = ToNumber(y); 149 return %Math_pow(x, y); 150} 151 152// ECMA 262 - 15.8.2.14 153function MathRandom() { 154 return %_RandomPositiveSmi() / 0x40000000; 155} 156 157// ECMA 262 - 15.8.2.15 158function MathRound(x) { 159 if (!IS_NUMBER(x)) x = ToNumber(x); 160 return %Math_round(x); 161} 162 163// ECMA 262 - 15.8.2.16 164function MathSin(x) { 165 if (!IS_NUMBER(x)) x = ToNumber(x); 166 return %_Math_sin(x); 167} 168 169// ECMA 262 - 15.8.2.17 170function MathSqrt(x) { 171 if (!IS_NUMBER(x)) x = ToNumber(x); 172 return %Math_sqrt(x); 173} 174 175// ECMA 262 - 15.8.2.18 176function MathTan(x) { 177 if (!IS_NUMBER(x)) x = ToNumber(x); 178 return %Math_tan(x); 179} 180 181 182// ------------------------------------------------------------------- 183 184function SetupMath() { 185 // Setup math constants. 186 // ECMA-262, section 15.8.1.1. 187 %OptimizeObjectForAddingMultipleProperties($Math, 8); 188 %SetProperty($Math, 189 "E", 190 2.7182818284590452354, 191 DONT_ENUM | DONT_DELETE | READ_ONLY); 192 // ECMA-262, section 15.8.1.2. 193 %SetProperty($Math, 194 "LN10", 195 2.302585092994046, 196 DONT_ENUM | DONT_DELETE | READ_ONLY); 197 // ECMA-262, section 15.8.1.3. 198 %SetProperty($Math, 199 "LN2", 200 0.6931471805599453, 201 DONT_ENUM | DONT_DELETE | READ_ONLY); 202 // ECMA-262, section 15.8.1.4. 203 %SetProperty($Math, 204 "LOG2E", 205 1.4426950408889634, 206 DONT_ENUM | DONT_DELETE | READ_ONLY); 207 %SetProperty($Math, 208 "LOG10E", 209 0.43429448190325176, 210 DONT_ENUM | DONT_DELETE | READ_ONLY); 211 %SetProperty($Math, 212 "PI", 213 3.1415926535897932, 214 DONT_ENUM | DONT_DELETE | READ_ONLY); 215 %SetProperty($Math, 216 "SQRT1_2", 217 0.7071067811865476, 218 DONT_ENUM | DONT_DELETE | READ_ONLY); 219 %SetProperty($Math, 220 "SQRT2", 221 1.4142135623730951, 222 DONT_ENUM | DONT_DELETE | READ_ONLY); 223 %TransformToFastProperties($Math); 224 225 // Setup non-enumerable functions of the Math object and 226 // set their names. 227 InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array( 228 "random", MathRandom, 229 "abs", MathAbs, 230 "acos", MathAcos, 231 "asin", MathAsin, 232 "atan", MathAtan, 233 "ceil", MathCeil, 234 "cos", MathCos, 235 "exp", MathExp, 236 "floor", MathFloor, 237 "log", MathLog, 238 "round", MathRound, 239 "sin", MathSin, 240 "sqrt", MathSqrt, 241 "tan", MathTan, 242 "atan2", MathAtan2, 243 "pow", MathPow, 244 "max", MathMax, 245 "min", MathMin 246 )); 247}; 248 249 250SetupMath(); 251