Home | History | Annotate | Download | only in src
      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.
     32 const $floor = MathFloor;
     33 const $random = MathRandom;
     34 const $abs = MathAbs;
     35 
     36 // Instance class name can only be set on functions. That is the only
     37 // purpose for MathConstructor.
     38 function MathConstructor() {}
     39 %FunctionSetInstanceClassName(MathConstructor, 'Math');
     40 const $Math = new MathConstructor();
     41 $Math.__proto__ = global.Object.prototype;
     42 %SetProperty(global, "Math", $Math, DONT_ENUM);
     43 
     44 // ECMA 262 - 15.8.2.1
     45 function MathAbs(x) {
     46   if (%_IsSmi(x)) return x >= 0 ? x : -x;
     47   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
     48   if (x === 0) return 0;  // To handle -0.
     49   return x > 0 ? x : -x;
     50 }
     51 
     52 // ECMA 262 - 15.8.2.2
     53 function MathAcos(x) {
     54   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
     55   return %Math_acos(x);
     56 }
     57 
     58 // ECMA 262 - 15.8.2.3
     59 function MathAsin(x) {
     60   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
     61   return %Math_asin(x);
     62 }
     63 
     64 // ECMA 262 - 15.8.2.4
     65 function MathAtan(x) {
     66   if (!IS_NUMBER(x)) x = NonNumberToNumber(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.
     73 function MathAtan2(y, x) {
     74   if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
     75   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
     76   return %Math_atan2(y, x);
     77 }
     78 
     79 // ECMA 262 - 15.8.2.6
     80 function MathCeil(x) {
     81   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
     82   return %Math_ceil(x);
     83 }
     84 
     85 // ECMA 262 - 15.8.2.7
     86 function MathCos(x) {
     87   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
     88   return %_MathCos(x);
     89 }
     90 
     91 // ECMA 262 - 15.8.2.8
     92 function MathExp(x) {
     93   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
     94   return %Math_exp(x);
     95 }
     96 
     97 // ECMA 262 - 15.8.2.9
     98 function MathFloor(x) {
     99   if (!IS_NUMBER(x)) x = NonNumberToNumber(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 < 0x80000000 && 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 TO_UINT32(x);
    108   } else {
    109     return %Math_floor(x);
    110   }
    111 }
    112 
    113 // ECMA 262 - 15.8.2.10
    114 function MathLog(x) {
    115   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
    116   return %_MathLog(x);
    117 }
    118 
    119 // ECMA 262 - 15.8.2.11
    120 function MathMax(arg1, arg2) {  // length == 2
    121   var length = %_ArgumentsLength();
    122   if (length == 0) {
    123     return -1/0;  // Compiler constant-folds this to -Infinity.
    124   }
    125   var r = arg1;
    126   if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
    127   if (NUMBER_IS_NAN(r)) return r;
    128   for (var i = 1; i < length; i++) {
    129     var n = %_Arguments(i);
    130     if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
    131     if (NUMBER_IS_NAN(n)) return n;
    132     // 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;
    135   }
    136   return r;
    137 }
    138 
    139 // ECMA 262 - 15.8.2.12
    140 function MathMin(arg1, arg2) {  // length == 2
    141   var length = %_ArgumentsLength();
    142   if (length == 0) {
    143     return 1/0;  // Compiler constant-folds this to Infinity.
    144   }
    145   var r = arg1;
    146   if (!IS_NUMBER(r)) r = NonNumberToNumber(r);
    147   if (NUMBER_IS_NAN(r)) return r;
    148   for (var i = 1; i < length; i++) {
    149     var n = %_Arguments(i);
    150     if (!IS_NUMBER(n)) n = NonNumberToNumber(n);
    151     if (NUMBER_IS_NAN(n)) return n;
    152     // 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;
    155   }
    156   return r;
    157 }
    158 
    159 // ECMA 262 - 15.8.2.13
    160 function MathPow(x, y) {
    161   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
    162   if (!IS_NUMBER(y)) y = NonNumberToNumber(y);
    163   return %_MathPow(x, y);
    164 }
    165 
    166 // ECMA 262 - 15.8.2.14
    167 function MathRandom() {
    168   return %_RandomHeapNumber();
    169 }
    170 
    171 // ECMA 262 - 15.8.2.15
    172 function MathRound(x) {
    173   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
    174   return %RoundNumber(x);
    175 }
    176 
    177 // ECMA 262 - 15.8.2.16
    178 function MathSin(x) {
    179   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
    180   return %_MathSin(x);
    181 }
    182 
    183 // ECMA 262 - 15.8.2.17
    184 function MathSqrt(x) {
    185   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
    186   return %_MathSqrt(x);
    187 }
    188 
    189 // ECMA 262 - 15.8.2.18
    190 function MathTan(x) {
    191   if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
    192   return %Math_tan(x);
    193 }
    194 
    195 
    196 // -------------------------------------------------------------------
    197 
    198 function SetupMath() {
    199   // Setup math constants.
    200   // ECMA-262, section 15.8.1.1.
    201   %OptimizeObjectForAddingMultipleProperties($Math, 8);
    202   %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",
    223                0.4342944819032518,
    224                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);
    237   %ToFastProperties($Math);
    238 
    239   // Setup non-enumerable functions of the Math object and
    240   // set their names.
    241   InstallFunctionsOnHiddenPrototype($Math, DONT_ENUM, $Array(
    242     "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 };
    262 
    263 
    264 SetupMath();
    265