1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nashorn.internal.objects;
  27 
  28 import jdk.nashorn.internal.objects.annotations.Attribute;
  29 import jdk.nashorn.internal.objects.annotations.Function;
  30 import jdk.nashorn.internal.objects.annotations.Property;
  31 import jdk.nashorn.internal.objects.annotations.ScriptClass;
  32 import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
  33 import jdk.nashorn.internal.objects.annotations.Where;
  34 import jdk.nashorn.internal.runtime.JSType;
  35 import jdk.nashorn.internal.runtime.PropertyMap;
  36 import jdk.nashorn.internal.runtime.ScriptObject;
  37 
  38 /**
  39  * ECMA 15.8 The Math Object
  40  *
  41  */
  42 @ScriptClass("Math")
  43 public final class NativeMath extends ScriptObject {
  44 
  45     // initialized by nasgen
  46     @SuppressWarnings("unused")
  47     private static PropertyMap $nasgenmap$;
  48 
  49     private NativeMath() {
  50         // don't create me!
  51         throw new UnsupportedOperationException();
  52     }
  53 
  54     /** ECMA 15.8.1.1 - E, always a double constant. Not writable or configurable */
  55     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  56     public static final double E = Math.E;
  57 
  58     /** ECMA 15.8.1.2 - LN10, always a double constant. Not writable or configurable */
  59     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  60     public static final double LN10 = 2.302585092994046;
  61 
  62     /** ECMA 15.8.1.3 - LN2, always a double constant. Not writable or configurable */
  63     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  64     public static final double LN2 = 0.6931471805599453;
  65 
  66     /** ECMA 15.8.1.4 - LOG2E, always a double constant. Not writable or configurable */
  67     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  68     public static final double LOG2E = 1.4426950408889634;
  69 
  70     /** ECMA 15.8.1.5 - LOG10E, always a double constant. Not writable or configurable */
  71     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  72     public static final double LOG10E = 0.4342944819032518;
  73 
  74     /** ECMA 15.8.1.6 - PI, always a double constant. Not writable or configurable */
  75     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  76     public static final double PI = Math.PI;
  77 
  78     /** ECMA 15.8.1.7 - SQRT1_2, always a double constant. Not writable or configurable */
  79     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  80     public static final double SQRT1_2 = 0.7071067811865476;
  81 
  82     /** ECMA 15.8.1.8 - SQRT2, always a double constant. Not writable or configurable */
  83     @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
  84     public static final double SQRT2 = 1.4142135623730951;
  85 
  86     /**
  87      * ECMA 15.8.2.1 abs(x)
  88      *
  89      * @param self  self reference
  90      * @param x     argument
  91      *
  92      * @return abs of value
  93      */
  94     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
  95     public static double abs(final Object self, final Object x) {
  96         return Math.abs(JSType.toNumber(x));
  97     }
  98 
  99     /**
 100      * ECMA 15.8.2.1 abs(x) - specialization for int values
 101      *
 102      * @param self  self reference
 103      * @param x     argument
 104      *
 105      * @return abs of argument
 106      */
 107     @SpecializedFunction
 108     public static double abs(final Object self, final int x) {
 109         return x == Integer.MIN_VALUE? Math.abs((double)x) : Math.abs(x);
 110     }
 111 
 112     /**
 113      * ECMA 15.8.2.1 abs(x) - specialization for long values
 114      *
 115      * @param self  self reference
 116      * @param x     argument
 117      *
 118      * @return abs of argument
 119      */
 120     @SpecializedFunction
 121     public static long abs(final Object self, final long x) {
 122         return Math.abs(x);
 123     }
 124 
 125     /**
 126      * ECMA 15.8.2.1 abs(x) - specialization for double values
 127      *
 128      * @param self  self reference
 129      * @param x     argument
 130      *
 131      * @return abs of argument
 132      */
 133     @SpecializedFunction
 134     public static double abs(final Object self, final double x) {
 135         return Math.abs(x);
 136     }
 137 
 138     /**
 139      * ECMA 15.8.2.2 acos(x)
 140      *
 141      * @param self  self reference
 142      * @param x     argument
 143      *
 144      * @return acos of argument
 145      */
 146     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 147     public static double acos(final Object self, final Object x) {
 148         return Math.acos(JSType.toNumber(x));
 149     }
 150 
 151     /**
 152      * ECMA 15.8.2.2 acos(x) - specialization for double values
 153      *
 154      * @param self  self reference
 155      * @param x     argument
 156      *
 157      * @return acos of argument
 158      */
 159     @SpecializedFunction
 160     public static double acos(final Object self, final double x) {
 161         return Math.acos(x);
 162     }
 163 
 164     /**
 165      * ECMA 15.8.2.3 asin(x)
 166      *
 167      * @param self  self reference
 168      * @param x     argument
 169      *
 170      * @return asin of argument
 171      */
 172     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 173     public static double asin(final Object self, final Object x) {
 174         return Math.asin(JSType.toNumber(x));
 175     }
 176 
 177     /**
 178      * ECMA 15.8.2.3 asin(x) - specialization for double values
 179      *
 180      * @param self  self reference
 181      * @param x     argument
 182      *
 183      * @return asin of argument
 184      */
 185     @SpecializedFunction
 186     public static double asin(final Object self, final double x) {
 187         return Math.asin(x);
 188     }
 189 
 190     /**
 191      * ECMA 15.8.2.4 atan(x)
 192      *
 193      * @param self  self reference
 194      * @param x     argument
 195      *
 196      * @return atan of argument
 197      */
 198     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 199     public static double atan(final Object self, final Object x) {
 200         return Math.atan(JSType.toNumber(x));
 201     }
 202 
 203     /**
 204      * ECMA 15.8.2.4 atan(x) - specialization for double values
 205      *
 206      * @param self  self reference
 207      * @param x     argument
 208      *
 209      * @return atan of argument
 210      */
 211     @SpecializedFunction
 212     public static double atan(final Object self, final double x) {
 213         return Math.atan(x);
 214     }
 215 
 216     /**
 217      * ECMA 15.8.2.5 atan2(x,y)
 218      *
 219      * @param self  self reference
 220      * @param x     first argument
 221      * @param y     second argument
 222      *
 223      * @return atan2 of x and y
 224      */
 225     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 226     public static double atan2(final Object self, final Object y, final Object x) {
 227         return Math.atan2(JSType.toNumber(y), JSType.toNumber(x));
 228     }
 229 
 230     /**
 231      * ECMA 15.8.2.5 atan2(x,y) - specialization for double values
 232      *
 233      * @param self  self reference
 234      * @param x     first argument
 235      * @param y     second argument
 236      *
 237      * @return atan2 of x and y
 238      */
 239     @SpecializedFunction
 240     public static double atan2(final Object self, final double y, final double x) {
 241         return Math.atan2(y,x);
 242     }
 243 
 244     /**
 245      * ECMA 15.8.2.6 ceil(x)
 246      *
 247      * @param self  self reference
 248      * @param x     argument
 249      *
 250      * @return ceil of argument
 251      */
 252     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 253     public static double ceil(final Object self, final Object x) {
 254         return Math.ceil(JSType.toNumber(x));
 255     }
 256 
 257     /**
 258      * ECMA 15.8.2.6 ceil(x) - specialized version for ints
 259      *
 260      * @param self  self reference
 261      * @param x     argument
 262      *
 263      * @return ceil of argument
 264      */
 265     @SpecializedFunction
 266     public static int ceil(final Object self, final int x) {
 267         return x;
 268     }
 269 
 270     /**
 271      * ECMA 15.8.2.6 ceil(x) - specialized version for longs
 272      *
 273      * @param self  self reference
 274      * @param x     argument
 275      *
 276      * @return ceil of argument
 277      */
 278     @SpecializedFunction
 279     public static long ceil(final Object self, final long x) {
 280         return x;
 281     }
 282 
 283     /**
 284      * ECMA 15.8.2.6 ceil(x) - specialized version for doubles
 285      *
 286      * @param self  self reference
 287      * @param x     argument
 288      *
 289      * @return ceil of argument
 290      */
 291     @SpecializedFunction
 292     public static double ceil(final Object self, final double x) {
 293         return Math.ceil(x);
 294     }
 295 
 296     /**
 297      * ECMA 15.8.2.7 cos(x)
 298      *
 299      * @param self  self reference
 300      * @param x     argument
 301      *
 302      * @return cos of argument
 303      */
 304     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 305     public static double cos(final Object self, final Object x) {
 306         return Math.cos(JSType.toNumber(x));
 307     }
 308 
 309     /**
 310      * ECMA 15.8.2.7 cos(x) - specialized version for doubles
 311      *
 312      * @param self  self reference
 313      * @param x     argument
 314      *
 315      * @return cos of argument
 316      */
 317     @SpecializedFunction
 318     public static double cos(final Object self, final double x) {
 319         return Math.cos(x);
 320     }
 321 
 322     /**
 323      * ECMA 15.8.2.8 exp(x)
 324      *
 325      * @param self  self reference
 326      * @param x     argument
 327      *
 328      * @return exp of argument
 329      */
 330     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 331     public static double exp(final Object self, final Object x) {
 332         return Math.exp(JSType.toNumber(x));
 333     }
 334 
 335     /**
 336      * ECMA 15.8.2.9 floor(x)
 337      *
 338      * @param self  self reference
 339      * @param x     argument
 340      *
 341      * @return floor of argument
 342      */
 343     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 344     public static double floor(final Object self, final Object x) {
 345         return Math.floor(JSType.toNumber(x));
 346     }
 347 
 348     /**
 349      * ECMA 15.8.2.9 floor(x) - specialized version for ints
 350      *
 351      * @param self  self reference
 352      * @param x     argument
 353      *
 354      * @return floor of argument
 355      */
 356     @SpecializedFunction
 357     public static int floor(final Object self, final int x) {
 358         return x;
 359     }
 360 
 361     /**
 362      * ECMA 15.8.2.9 floor(x) - specialized version for longs
 363      *
 364      * @param self  self reference
 365      * @param x     argument
 366      *
 367      * @return floor of argument
 368      */
 369     @SpecializedFunction
 370     public static long floor(final Object self, final long x) {
 371         return x;
 372     }
 373 
 374     /**
 375      * ECMA 15.8.2.9 floor(x) - specialized version for doubles
 376      *
 377      * @param self  self reference
 378      * @param x     argument
 379      *
 380      * @return floor of argument
 381      */
 382     @SpecializedFunction
 383     public static double floor(final Object self, final double x) {
 384         return Math.floor(x);
 385     }
 386 
 387     /**
 388      * ECMA 15.8.2.10 log(x)
 389      *
 390      * @param self  self reference
 391      * @param x     argument
 392      *
 393      * @return log of argument
 394      */
 395     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 396     public static double log(final Object self, final Object x) {
 397         return Math.log(JSType.toNumber(x));
 398     }
 399 
 400     /**
 401      * ECMA 15.8.2.10 log(x) - specialized version for doubles
 402      *
 403      * @param self  self reference
 404      * @param x     argument
 405      *
 406      * @return log of argument
 407      */
 408     @SpecializedFunction
 409     public static double log(final Object self, final double x) {
 410         return Math.log(x);
 411     }
 412 
 413     /**
 414      * ECMA 15.8.2.11 max(x)
 415      *
 416      * @param self  self reference
 417      * @param args  arguments
 418      *
 419      * @return the largest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
 420      */
 421     @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 422     public static double max(final Object self, final Object... args) {
 423         switch (args.length) {
 424         case 0:
 425             return Double.NEGATIVE_INFINITY;
 426         case 1:
 427             return JSType.toNumber(args[0]);
 428         default:
 429             double res = JSType.toNumber(args[0]);
 430             for (int i = 1; i < args.length; i++) {
 431                 res = Math.max(res, JSType.toNumber(args[i]));
 432             }
 433             return res;
 434         }
 435     }
 436 
 437     /**
 438      * ECMA 15.8.2.11 max(x) - specialized no args version
 439      *
 440      * @param self  self reference
 441      *
 442      * @return {@link Double#NEGATIVE_INFINITY}
 443      */
 444     @SpecializedFunction
 445     public static double max(final Object self) {
 446         return Double.NEGATIVE_INFINITY;
 447     }
 448 
 449     /**
 450      * ECMA 15.8.2.11 max(x) - specialized version for ints
 451      *
 452      * @param self  self reference
 453      * @param x     first argument
 454      * @param y     second argument
 455      *
 456      * @return largest value of x and y
 457      */
 458     @SpecializedFunction
 459     public static int max(final Object self, final int x, final int y) {
 460         return Math.max(x, y);
 461     }
 462 
 463     /**
 464      * ECMA 15.8.2.11 max(x) - specialized version for longs
 465      *
 466      * @param self  self reference
 467      * @param x     first argument
 468      * @param y     second argument
 469      *
 470      * @return largest value of x and y
 471      */
 472     @SpecializedFunction
 473     public static long max(final Object self, final long x, final long y) {
 474         return Math.max(x, y);
 475     }
 476 
 477     /**
 478      * ECMA 15.8.2.11 max(x) - specialized version for doubles
 479      *
 480      * @param self  self reference
 481      * @param x     first argument
 482      * @param y     second argument
 483      *
 484      * @return largest value of x and y
 485      */
 486     @SpecializedFunction
 487     public static double max(final Object self, final double x, final double y) {
 488         return Math.max(x, y);
 489     }
 490 
 491     /**
 492      * ECMA 15.8.2.11 max(x) - specialized version for two Object args
 493      *
 494      * @param self  self reference
 495      * @param x     first argument
 496      * @param y     second argument
 497      *
 498      * @return largest value of x and y
 499      */
 500     @SpecializedFunction
 501     public static double max(final Object self, final Object x, final Object y) {
 502         return Math.max(JSType.toNumber(x), JSType.toNumber(y));
 503     }
 504 
 505     /**
 506      * ECMA 15.8.2.12 min(x)
 507      *
 508      * @param self  self reference
 509      * @param args  arguments
 510      *
 511      * @return the smallest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
 512      */
 513     @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 514     public static double min(final Object self, final Object... args) {
 515         switch (args.length) {
 516         case 0:
 517             return Double.POSITIVE_INFINITY;
 518         case 1:
 519             return JSType.toNumber(args[0]);
 520         default:
 521             double res = JSType.toNumber(args[0]);
 522             for (int i = 1; i < args.length; i++) {
 523                 res = Math.min(res, JSType.toNumber(args[i]));
 524             }
 525             return res;
 526         }
 527     }
 528 
 529     /**
 530      * ECMA 15.8.2.11 min(x) - specialized no args version
 531      *
 532      * @param self  self reference
 533      *
 534      * @return {@link Double#POSITIVE_INFINITY}
 535      */
 536     @SpecializedFunction
 537     public static double min(final Object self) {
 538         return Double.POSITIVE_INFINITY;
 539     }
 540 
 541     /**
 542      * ECMA 15.8.2.12 min(x) - specialized version for ints
 543      *
 544      * @param self  self reference
 545      * @param x     first argument
 546      * @param y     second argument
 547      *
 548      * @return smallest value of x and y
 549      */
 550     @SpecializedFunction
 551     public static int min(final Object self, final int x, final int y) {
 552         return Math.min(x, y);
 553     }
 554 
 555     /**
 556      * ECMA 15.8.2.12 min(x) - specialized version for longs
 557      *
 558      * @param self  self reference
 559      * @param x     first argument
 560      * @param y     second argument
 561      *
 562      * @return smallest value of x and y
 563      */
 564     @SpecializedFunction
 565     public static long min(final Object self, final long x, final long y) {
 566         return Math.min(x, y);
 567     }
 568 
 569     /**
 570      * ECMA 15.8.2.12 min(x) - specialized version for doubles
 571      *
 572      * @param self  self reference
 573      * @param x     first argument
 574      * @param y     second argument
 575      *
 576      * @return smallest value of x and y
 577      */
 578     @SpecializedFunction
 579     public static double min(final Object self, final double x, final double y) {
 580         return Math.min(x, y);
 581     }
 582 
 583     /**
 584      * ECMA 15.8.2.12 min(x) - specialized version for two Object args
 585      *
 586      * @param self  self reference
 587      * @param x     first argument
 588      * @param y     second argument
 589      *
 590      * @return smallest value of x and y
 591      */
 592     @SpecializedFunction
 593     public static double min(final Object self, final Object x, final Object y) {
 594         return Math.min(JSType.toNumber(x), JSType.toNumber(y));
 595     }
 596 
 597     /**
 598      * ECMA 15.8.2.13 pow(x,y)
 599      *
 600      * @param self  self reference
 601      * @param x     first argument
 602      * @param y     second argument
 603      *
 604      * @return x raised to the power of y
 605      */
 606     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 607     public static double pow(final Object self, final Object x, final Object y) {
 608         return Math.pow(JSType.toNumber(x), JSType.toNumber(y));
 609     }
 610 
 611     /**
 612      * ECMA 15.8.2.13 pow(x,y) - specialized version for doubles
 613      *
 614      * @param self  self reference
 615      * @param x     first argument
 616      * @param y     second argument
 617      *
 618      * @return x raised to the power of y
 619      */
 620     @SpecializedFunction
 621     public static double pow(final Object self, final double x, final double y) {
 622         return Math.pow(x, y);
 623     }
 624 
 625     /**
 626      * ECMA 15.8.2.14 random()
 627      *
 628      * @param self  self reference
 629      *
 630      * @return random number in the range [0..1)
 631      */
 632     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 633     public static double random(final Object self) {
 634         return Math.random();
 635     }
 636 
 637     /**
 638      * ECMA 15.8.2.15 round(x)
 639      *
 640      * @param self  self reference
 641      * @param x     argument
 642      *
 643      * @return x rounded
 644      */
 645     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 646     public static double round(final Object self, final Object x) {
 647         final double d = JSType.toNumber(x);
 648         if (Math.getExponent(d) >= 52) {
 649             return d;
 650         }
 651         return Math.copySign(Math.floor(d + 0.5), d);
 652     }
 653 
 654     /**
 655      * ECMA 15.8.2.16 sin(x)
 656      *
 657      * @param self  self reference
 658      * @param x     argument
 659      *
 660      * @return sin of x
 661      */
 662     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 663     public static double sin(final Object self, final Object x) {
 664         return Math.sin(JSType.toNumber(x));
 665     }
 666 
 667     /**
 668      * ECMA 15.8.2.16 sin(x) - specialized version for doubles
 669      *
 670      * @param self  self reference
 671      * @param x     argument
 672      *
 673      * @return sin of x
 674      */
 675     @SpecializedFunction
 676     public static double sin(final Object self, final double x) {
 677         return Math.sin(x);
 678     }
 679 
 680     /**
 681      * ECMA 15.8.2.17 sqrt(x)
 682      *
 683      * @param self  self reference
 684      * @param x     argument
 685      *
 686      * @return sqrt of x
 687      */
 688     @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
 689     public static double sqrt(final Object self, final Object x) {
 690         return Math.sqrt(JSType.toNumber(x));
 691     }
 692 
 693     /**
 694      * ECMA 15.8.2.17 sqrt(x) - specialized version for doubles
 695      *
 696      * @param self  self reference
 697      * @param x     argument
 698      *
 699      * @return sqrt of x
 700      */
 701     @SpecializedFunction
 702     public static double sqrt(final Object self, final double x) {
 703         return Math.sqrt(x);
 704     }
 705 
 706     /**
 707      * ECMA 15.8.2.18 tan(x)
 708      *
 709      * @param self  self reference
 710      * @param x     argument
 711      *
 712      * @return tan of x
 713      */
 714     @Function(attributes = Attribute.NOT_ENUMERABLE, where=Where.CONSTRUCTOR)
 715     public static double tan(final Object self, final Object x) {
 716         return Math.tan(JSType.toNumber(x));
 717     }
 718 
 719     /**
 720      * ECMA 15.8.2.18 tan(x) - specialized version for doubles
 721      *
 722      * @param self  self reference
 723      * @param x     argument
 724      *
 725      * @return tan of x
 726      */
 727     @SpecializedFunction
 728     public static double tan(final Object self, final double x) {
 729         return Math.tan(x);
 730     }
 731 }