aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/objects/NativeNumber.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/objects/NativeNumber.java')
-rw-r--r--src/jdk/nashorn/internal/objects/NativeNumber.java390
1 files changed, 0 insertions, 390 deletions
diff --git a/src/jdk/nashorn/internal/objects/NativeNumber.java b/src/jdk/nashorn/internal/objects/NativeNumber.java
deleted file mode 100644
index b72080b8..00000000
--- a/src/jdk/nashorn/internal/objects/NativeNumber.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.nashorn.internal.objects;
-
-import static jdk.nashorn.internal.lookup.Lookup.MH;
-import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
-import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
-import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.math.RoundingMode;
-import java.text.NumberFormat;
-import java.util.Locale;
-import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.internal.dynalink.linker.LinkRequest;
-import jdk.nashorn.internal.objects.annotations.Attribute;
-import jdk.nashorn.internal.objects.annotations.Constructor;
-import jdk.nashorn.internal.objects.annotations.Function;
-import jdk.nashorn.internal.objects.annotations.Property;
-import jdk.nashorn.internal.objects.annotations.ScriptClass;
-import jdk.nashorn.internal.objects.annotations.SpecializedFunction;
-import jdk.nashorn.internal.objects.annotations.Where;
-import jdk.nashorn.internal.runtime.JSType;
-import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptObject;
-import jdk.nashorn.internal.runtime.ScriptRuntime;
-import jdk.nashorn.internal.runtime.linker.NashornGuards;
-import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
-
-/**
- * ECMA 15.7 Number Objects.
- *
- */
-@ScriptClass("Number")
-public final class NativeNumber extends ScriptObject {
-
- /** Method handle to create an object wrapper for a primitive number. */
- static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeNumber.class, Object.class));
- /** Method handle to retrieve the Number prototype object. */
- private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
-
- /** ECMA 15.7.3.2 largest positive finite value */
- @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
- public static final double MAX_VALUE = Double.MAX_VALUE;
-
- /** ECMA 15.7.3.3 smallest positive finite value */
- @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
- public static final double MIN_VALUE = Double.MIN_VALUE;
-
- /** ECMA 15.7.3.4 NaN */
- @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
- public static final double NaN = Double.NaN;
-
- /** ECMA 15.7.3.5 negative infinity */
- @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
- public static final double NEGATIVE_INFINITY = Double.NEGATIVE_INFINITY;
-
- /** ECMA 15.7.3.5 positive infinity */
- @Property(attributes = Attribute.NON_ENUMERABLE_CONSTANT, where = Where.CONSTRUCTOR)
- public static final double POSITIVE_INFINITY = Double.POSITIVE_INFINITY;
-
- private final double value;
-
- // initialized by nasgen
- private static PropertyMap $nasgenmap$;
-
- private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
- super(proto, map);
- this.value = value;
- }
-
- NativeNumber(final double value, final Global global) {
- this(value, global.getNumberPrototype(), $nasgenmap$);
- }
-
- private NativeNumber(final double value) {
- this(value, Global.instance());
- }
-
-
- @Override
- public String safeToString() {
- return "[Number " + toString() + "]";
- }
-
- @Override
- public String toString() {
- return Double.toString(getValue());
- }
-
- /**
- * Get the value of this Number
- * @return a {@code double} representing the Number value
- */
- public double getValue() {
- return doubleValue();
- }
-
- /**
- * Get the value of this Number
- * @return a {@code double} representing the Number value
- */
- public double doubleValue() {
- return value;
- }
-
- @Override
- public String getClassName() {
- return "Number";
- }
-
- /**
- * ECMA 15.7.2 - The Number constructor
- *
- * @param newObj is this Number instantiated with the new operator
- * @param self self reference
- * @param args value of number
- * @return the Number instance (internally represented as a {@code NativeNumber})
- */
- @Constructor(arity = 1)
- public static Object constructor(final boolean newObj, final Object self, final Object... args) {
- final double num = (args.length > 0) ? JSType.toNumber(args[0]) : 0.0;
-
- return newObj? new NativeNumber(num) : num;
- }
-
- /**
- * ECMA 15.7.4.5 Number.prototype.toFixed (fractionDigits)
- *
- * @param self self reference
- * @param fractionDigits how many digits should be after the decimal point, 0 if undefined
- *
- * @return number in decimal fixed point notation
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static String toFixed(final Object self, final Object fractionDigits) {
- return toFixed(self, JSType.toInteger(fractionDigits));
- }
-
- /**
- * ECMA 15.7.4.5 Number.prototype.toFixed (fractionDigits) specialized for int fractionDigits
- *
- * @param self self reference
- * @param fractionDigits how many digits should be after the decimal point, 0 if undefined
- *
- * @return number in decimal fixed point notation
- */
- @SpecializedFunction
- public static String toFixed(final Object self, final int fractionDigits) {
- if (fractionDigits < 0 || fractionDigits > 20) {
- throw rangeError("invalid.fraction.digits", "toFixed");
- }
-
- final double x = getNumberValue(self);
- if (Double.isNaN(x)) {
- return "NaN";
- }
-
- if (Math.abs(x) >= 1e21) {
- return JSType.toString(x);
- }
-
- final NumberFormat format = NumberFormat.getNumberInstance(Locale.US);
- format.setMinimumFractionDigits(fractionDigits);
- format.setMaximumFractionDigits(fractionDigits);
- format.setGroupingUsed(false);
- format.setRoundingMode(RoundingMode.HALF_UP);
-
- return format.format(x);
- }
-
- /**
- * ECMA 15.7.4.6 Number.prototype.toExponential (fractionDigits)
- *
- * @param self self reference
- * @param fractionDigits how many digital should be after the significand's decimal point. If undefined, use as many as necessary to uniquely specify number.
- *
- * @return number in decimal exponential notation
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static String toExponential(final Object self, final Object fractionDigits) {
- final double x = getNumberValue(self);
- final boolean trimZeros = fractionDigits == UNDEFINED;
- final int f = trimZeros ? 16 : JSType.toInteger(fractionDigits);
-
- if (Double.isNaN(x)) {
- return "NaN";
- } else if (Double.isInfinite(x)) {
- return x > 0? "Infinity" : "-Infinity";
- }
-
- if (fractionDigits != UNDEFINED && (f < 0 || f > 20)) {
- throw rangeError("invalid.fraction.digits", "toExponential");
- }
-
- final String res = String.format(Locale.US, "%1." + f + "e", x);
- return fixExponent(res, trimZeros);
- }
-
- /**
- * ECMA 15.7.4.7 Number.prototype.toPrecision (precision)
- *
- * @param self self reference
- * @param precision use {@code precision - 1} digits after the significand's decimal point or call {@link JSType#toString} if undefined
- *
- * @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static String toPrecision(final Object self, final Object precision) {
- final double x = getNumberValue(self);
- if (precision == UNDEFINED) {
- return JSType.toString(x);
- }
- return (toPrecision(x, JSType.toInteger(precision)));
- }
-
- /**
- * ECMA 15.7.4.7 Number.prototype.toPrecision (precision) specialized f
- *
- * @param self self reference
- * @param precision use {@code precision - 1} digits after the significand's decimal point.
- *
- * @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
- */
- @SpecializedFunction
- public static String toPrecision(final Object self, final int precision) {
- return toPrecision(getNumberValue(self), precision);
- }
-
- private static String toPrecision(final double x, final int p) {
- if (Double.isNaN(x)) {
- return "NaN";
- } else if (Double.isInfinite(x)) {
- return x > 0? "Infinity" : "-Infinity";
- }
-
- if (p < 1 || p > 21) {
- throw rangeError("invalid.precision");
- }
-
- // workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6469160
- if (x == 0.0 && p <= 1) {
- return "0";
- }
-
- return fixExponent(String.format(Locale.US, "%." + p + "g", x), false);
- }
-
- /**
- * ECMA 15.7.4.2 Number.prototype.toString ( [ radix ] )
- *
- * @param self self reference
- * @param radix radix to use for string conversion
- * @return string representation of this Number in the given radix
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static String toString(final Object self, final Object radix) {
- if (radix != UNDEFINED) {
- final int intRadix = JSType.toInteger(radix);
- if (intRadix != 10) {
- if (intRadix < 2 || intRadix > 36) {
- throw rangeError("invalid.radix");
- }
- return JSType.toString(getNumberValue(self), intRadix);
- }
- }
-
- return JSType.toString(getNumberValue(self));
- }
-
- /**
- * ECMA 15.7.4.3 Number.prototype.toLocaleString()
- *
- * @param self self reference
- * @return localized string for this Number
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static String toLocaleString(final Object self) {
- return JSType.toString(getNumberValue(self));
- }
-
-
- /**
- * ECMA 15.7.4.4 Number.prototype.valueOf ( )
- *
- * @param self self reference
- * @return number value for this Number
- */
- @Function(attributes = Attribute.NOT_ENUMERABLE)
- public static double valueOf(final Object self) {
- return getNumberValue(self);
- }
-
- /**
- * Lookup the appropriate method for an invoke dynamic call.
- * @param request The link request
- * @param receiver receiver of call
- * @return Link to be invoked at call site.
- */
- public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
- return PrimitiveLookup.lookupPrimitive(request, NashornGuards.getNumberGuard(), new NativeNumber(((Number)receiver).doubleValue()), WRAPFILTER, PROTOFILTER);
- }
-
- @SuppressWarnings("unused")
- private static NativeNumber wrapFilter(final Object receiver) {
- return new NativeNumber(((Number)receiver).doubleValue());
- }
-
- @SuppressWarnings("unused")
- private static Object protoFilter(final Object object) {
- return Global.instance().getNumberPrototype();
- }
-
- private static double getNumberValue(final Object self) {
- if (self instanceof Number) {
- return ((Number)self).doubleValue();
- } else if (self instanceof NativeNumber) {
- return ((NativeNumber)self).getValue();
- } else if (self != null && self == Global.instance().getNumberPrototype()) {
- return 0.0;
- } else {
- throw typeError("not.a.number", ScriptRuntime.safeToString(self));
- }
- }
-
- // Exponent of Java "e" or "E" formatter is always 2 digits and zero
- // padded if needed (e+01, e+00, e+12 etc.) JS expects exponent to contain
- // exact number of digits e+1, e+0, e+12 etc. Fix the exponent here.
- //
- // Additionally, if trimZeros is true, this cuts trailing zeros in the
- // fraction part for calls to toExponential() with undefined fractionDigits
- // argument.
- private static String fixExponent(final String str, final boolean trimZeros) {
- final int index = str.indexOf('e');
- if (index < 1) {
- // no exponent, do nothing..
- return str;
- }
-
- // check if character after e+ or e- is 0
- final int expPadding = str.charAt(index + 2) == '0' ? 3 : 2;
- // check if there are any trailing zeroes we should remove
-
- int fractionOffset = index;
- if (trimZeros) {
- assert fractionOffset > 0;
- char c = str.charAt(fractionOffset - 1);
- while (fractionOffset > 1 && (c == '0' || c == '.')) {
- c = str.charAt(--fractionOffset - 1);
- }
-
- }
- // if anything needs to be done compose a new string
- if (fractionOffset < index || expPadding == 3) {
- return str.substring(0, fractionOffset)
- + str.substring(index, index + 2)
- + str.substring(index + expPadding);
- }
- return str;
- }
-
- private static MethodHandle findOwnMH(final String name, final MethodType type) {
- return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, name, type);
- }
-}