< prev index next >

src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/JSType.java

Print this page

        

@@ -117,18 +117,18 @@
 
     /** JavaScript compliant conversion function from double to int32 */
     public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class);
 
     /** JavaScript compliant conversion function from int to uint32 */
-    public static final Call TO_UINT32_I = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, int.class);
+    public static final Call TO_UINT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Optimistic", int.class, int.class, int.class);
+
+    /** JavaScript compliant conversion function from int to uint32 */
+    public static final Call TO_UINT32_DOUBLE = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Double", double.class, int.class);
 
     /** JavaScript compliant conversion function from Object to uint32 */
     public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class);
 
-    /** JavaScript compliant conversion function from Object to long with type check */
-    public static final Call TO_LONG_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toLongOptimistic", long.class, Object.class, int.class);
-
     /** JavaScript compliant conversion function from number to uint32 */
     public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class);
 
     /** JavaScript compliant conversion function from number to String */
     public static final Call TO_STRING_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, double.class);

@@ -170,40 +170,10 @@
     public static final Call INCREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact",   int.class, int.class, int.class);
 
     /** Negate exact exact wrapper for potentially overflowing integer operations */
     public static final Call NEGATE_EXACT         = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", int.class, int.class, int.class);
 
-    /** Add exact wrapper for potentially overflowing long operations */
-    public static final Call ADD_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", long.class, long.class, long.class, int.class);
-
-    /** Sub exact wrapper for potentially overflowing long operations */
-    public static final Call SUB_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", long.class, long.class, long.class, int.class);
-
-    /** Multiply exact wrapper for potentially overflowing long operations */
-    public static final Call MUL_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "mulExact", long.class, long.class, long.class, int.class);
-
-    /** Div exact wrapper for potentially integer division that turns into float point */
-    public static final Call DIV_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class);
-
-    /** Div zero wrapper for long division that handles (0/0) &gt;&gt;&gt; 0 == 0 */
-    public static final Call DIV_ZERO_LONG        = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class);
-
-    /** Mod zero wrapper for long division that handles (0%0) &gt;&gt;&gt; 0 == 0 */
-    public static final Call REM_ZERO_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class);
-
-    /** Mod exact wrapper for potentially integer remainders that turns into float point */
-    public static final Call REM_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", long.class, long.class, long.class, int.class);
-
-    /** Decrement exact wrapper for potentially overflowing long operations */
-    public static final Call DECREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact",  long.class, long.class, int.class);
-
-    /** Increment exact wrapper for potentially overflowing long operations */
-    public static final Call INCREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact",  long.class, long.class, int.class);
-
-    /** Negate exact exact wrapper for potentially overflowing long operations */
-    public static final Call NEGATE_EXACT_LONG    = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact",     long.class, long.class, int.class);
-
     /** Method handle to convert a JS Object to a Java array. */
     public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
 
     /** Method handle for void returns. */
     public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class);

@@ -213,40 +183,35 @@
      *  in the dual--fields world
      */
     private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
             Arrays.asList(
                 Type.INT,
-                Type.LONG,
                 Type.NUMBER,
                 Type.OBJECT));
 
     /** table index for undefined type - hard coded so it can be used in switches at compile time */
     public static final int TYPE_UNDEFINED_INDEX = -1;
     /** table index for integer type - hard coded so it can be used in switches at compile time */
     public static final int TYPE_INT_INDEX    = 0; //getAccessorTypeIndex(int.class);
-    /** table index for long type - hard coded so it can be used in switches at compile time */
-    public static final int TYPE_LONG_INDEX   = 1; //getAccessorTypeIndex(long.class);
     /** table index for double type - hard coded so it can be used in switches at compile time */
-    public static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
+    public static final int TYPE_DOUBLE_INDEX = 1; //getAccessorTypeIndex(double.class);
     /** table index for object type - hard coded so it can be used in switches at compile time */
-    public static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
+    public static final int TYPE_OBJECT_INDEX = 2; //getAccessorTypeIndex(Object.class);
 
     /** object conversion quickies with JS semantics - used for return value and parameter filter */
     public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList(
         JSType.TO_INT32.methodHandle(),
-        JSType.TO_UINT32.methodHandle(),
         JSType.TO_NUMBER.methodHandle(),
         null
     );
 
     /**
      * object conversion quickies with JS semantics - used for return value and parameter filter, optimistic
      * throws exception upon incompatible type (asking for a narrower one than the storage)
      */
     public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList(
         JSType.TO_INT32_OPTIMISTIC.methodHandle(),
-        JSType.TO_LONG_OPTIMISTIC.methodHandle(),
         JSType.TO_NUMBER_OPTIMISTIC.methodHandle(),
         null
     );
 
     /** The value of Undefined cast to an int32 */

@@ -254,17 +219,20 @@
     /** The value of Undefined cast to a long */
     public static final long   UNDEFINED_LONG   = 0L;
     /** The value of Undefined cast to a double */
     public static final double UNDEFINED_DOUBLE = Double.NaN;
 
+    // Minimum and maximum range between which every long value can be precisely represented as a double.
+    private static final long MAX_PRECISE_DOUBLE = 1L << 53;
+    private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
+
     /**
      * Method handles for getters that return undefined coerced
      * to the appropriate type
      */
     public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList(
         MH.constant(int.class, UNDEFINED_INT),
-        MH.constant(long.class, UNDEFINED_LONG),
         MH.constant(double.class, UNDEFINED_DOUBLE),
         MH.constant(Object.class, Undefined.getUndefined())
     );
 
     private static final double INT32_LIMIT = 4294967296.0;

@@ -426,43 +394,26 @@
         return false;
     }
 
     /**
      * Returns true if double number can be represented as a long. Note that it returns true for negative
-     * zero. If you need to exclude negative zero, use {@link #isStrictlyRepresentableAsLong(double)}.
+     * zero.
      *
      * @param number a double to inspect
      * @return true for long representable doubles
      */
     public static boolean isRepresentableAsLong(final double number) {
         return (long)number == number;
     }
 
     /**
-     * Returns true if double number can be represented as a long. Note that it returns false for negative
-     * zero. If you don't need to distinguish negative zero, use {@link #isRepresentableAsLong(double)}.
-     *
-     * @param number a double to inspect
-     *
-     * @return true for long representable doubles
+     * Returns true if long number can be represented as double without loss of precision.
+     * @param number a long number
+     * @return true if the double representation does not lose precision
      */
-    public static boolean isStrictlyRepresentableAsLong(final double number) {
-        return isRepresentableAsLong(number) && isNotNegativeZero(number);
-    }
-
-    /**
-     * Returns true if Object can be represented as a long
-     *
-     * @param obj an object to inspect
-     *
-     * @return true for long representable objects
-     */
-    public static boolean isRepresentableAsLong(final Object obj) {
-        if (obj instanceof Number) {
-            return isRepresentableAsLong(((Number)obj).doubleValue());
-        }
-        return false;
+    public static boolean isRepresentableAsDouble(final long number) {
+        return MAX_PRECISE_DOUBLE >= number && number >= MIN_PRECISE_DOUBLE;
     }
 
     /**
      * Returns true if the number is not the negative zero ({@code -0.0d}).
      * @param number the number to test

@@ -648,26 +599,10 @@
         }
         return toString(obj);
     }
 
     /**
-     * Check whether a string is representable as a JavaScript number
-     *
-     * @param str  a string
-     *
-     * @return     true if string can be represented as a number
-     */
-    public static boolean isNumber(final String str) {
-        try {
-            Double.parseDouble(str);
-            return true;
-        } catch (final NumberFormatException e) {
-            return false;
-        }
-    }
-
-    /**
      * Returns true if object represents a primitive JavaScript string value.
      * @param obj the object
      * @return true if the object represents a primitive JavaScript string value.
      */
     public static boolean isString(final Object obj) {

@@ -1031,39 +966,10 @@
     public static long toLong(final double num) {
         return (long)num;
     }
 
     /**
-     * Optimistic long conversion - throws UnwarrantedOptimismException if double or Object
-     *
-     * @param obj           object to convert
-     * @param programPoint  program point
-     * @return long
-     */
-    public static long toLongOptimistic(final Object obj, final int programPoint) {
-        if (obj != null) {
-            final Class<?> clz = obj.getClass();
-            if (clz == Long.class || clz == Integer.class) {
-                return ((Number)obj).longValue();
-            }
-        }
-        throw new UnwarrantedOptimismException(obj, programPoint);
-    }
-
-    /**
-     * Object to int conversion that delegates to either {@link #toLong(Object)} or to
-     * {@link #toLongOptimistic(Object, int)} depending on whether the program point is valid or not.
-     * @param obj the object to convert
-     * @param programPoint the program point; can be invalid.
-     * @return the value converted to long
-     * @throws UnwarrantedOptimismException if the value can't be represented as long and the program point is valid.
-     */
-    public static long toLongMaybeOptimistic(final Object obj, final int programPoint) {
-        return UnwarrantedOptimismException.isValid(programPoint) ? toLongOptimistic(obj, programPoint) : toLong(obj);
-    }
-
-    /**
      * JavaScript compliant Object to int32 conversion
      * See ECMA 9.5 ToInt32
      *
      * @param obj an object
      * @return an int32

@@ -1096,14 +1002,10 @@
      */
     public static int toInt32MaybeOptimistic(final Object obj, final int programPoint) {
         return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj);
     }
 
-    // Minimum and maximum range between which every long value can be precisely represented as a double.
-    private static final long MAX_PRECISE_DOUBLE = 1L << 53;
-    private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
-
     /**
      * JavaScript compliant long to int32 conversion
      *
      * @param num a long
      * @return an int32

@@ -1152,10 +1054,33 @@
     public static long toUint32(final int num) {
         return num & MAX_UINT;
     }
 
     /**
+     * Optimistic JavaScript compliant int to uint32 conversion
+     * @param num an int
+     * @param pp the program point
+     * @return the uint32 value if it can be represented by an int
+     * @throws UnwarrantedOptimismException if uint32 value cannot be represented by an int
+     */
+    public static int toUint32Optimistic(final int num, final int pp) {
+        if (num >= 0) {
+            return num;
+        }
+        throw new UnwarrantedOptimismException(toUint32Double(num), pp, Type.NUMBER);
+    }
+
+    /**
+     * JavaScript compliant int to uint32 conversion with double return type
+     * @param num an int
+     * @return the uint32 value as double
+     */
+    public static double toUint32Double(final int num) {
+        return (double) toUint32(num);
+    }
+
+    /**
      * JavaScript compliant Object to uint16 conversion
      * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
      *
      * @param obj an object
      * @return a uint16

@@ -1482,30 +1407,10 @@
      */
     public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
         try {
             return Math.addExact(x, y);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x + (long)y, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for addExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long addExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.addExact(x, y);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException((double)x + (double)y, programPoint);
         }
     }
 
     /**

@@ -1522,30 +1427,10 @@
      */
     public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
         try {
             return Math.subtractExact(x, y);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x - (long)y, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for subExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long subExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.subtractExact(x, y);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException((double)x - (double)y, programPoint);
         }
     }
 
     /**

@@ -1562,30 +1447,10 @@
      */
     public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
         try {
             return Math.multiplyExact(x, y);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x * (long)y, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for mulExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long mulExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.multiplyExact(x, y);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException((double)x * (double)y, programPoint);
         }
     }
 
     /**

@@ -1653,75 +1518,10 @@
             throw new UnwarrantedOptimismException(Double.NaN, programPoint);
         }
     }
 
     /**
-     * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
-     * long.
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if the result of the division can't be represented as long.
-     */
-    public static long divExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        final long res;
-        try {
-            res = x / y;
-        } catch (final ArithmeticException e) {
-            assert y == 0L; // Only div by zero anticipated
-            throw new UnwarrantedOptimismException(x > 0L ? Double.POSITIVE_INFINITY : x < 0L ? Double.NEGATIVE_INFINITY : Double.NaN, programPoint);
-        }
-        final long rem = x % y;
-        if (rem == 0L) {
-            return res;
-        }
-        throw new UnwarrantedOptimismException((double)x / (double)y, programPoint);
-    }
-
-    /**
-     * Implements long division but allows {@code x / 0} to be represented as 0. Useful when division of two longs
-     * is coerced to long.
-     * @param x the dividend
-     * @param y the divisor
-     * @return the result
-     */
-    public static long divZero(final long x, final long y) {
-        return y == 0L ? 0L : x / y;
-    }
-
-    /**
-     * Implements long remainder but allows {@code x % 0} to be represented as 0. Useful when remainder of two longs
-     * is coerced to long.
-     * @param x the dividend
-     * @param y the divisor
-     * @return the remainder
-     */
-    public static long remZero(final long x, final long y) {
-        return y == 0L ? 0L : x % y;
-    }
-
-    /**
-     * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
-     *
-     * @param x first term
-     * @param y second term
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
-     */
-    public static long remExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return x % y;
-        } catch (final ArithmeticException e) {
-            assert y == 0L; // Only mod by zero anticipated
-            throw new UnwarrantedOptimismException(Double.NaN, programPoint);
-        }
-    }
-
-    /**
      * Wrapper for decrementExact
      *
      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
      * containing the result and the program point of the failure
      *

@@ -1732,30 +1532,11 @@
      */
     public static int decrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
         try {
             return Math.decrementExact(x);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x - 1, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for decrementExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x number to negate
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long decrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.decrementExact(x);
-        } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((double)x - 1L, programPoint);
+            throw new UnwarrantedOptimismException((double)x - 1, programPoint);
         }
     }
 
     /**
      * Wrapper for incrementExact

@@ -1770,30 +1551,11 @@
      */
     public static int incrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
         try {
             return Math.incrementExact(x);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((long)x + 1, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for incrementExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x the number to increment
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long incrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            return Math.incrementExact(x);
-        } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException((double)x + 1L, programPoint);
+            throw new UnwarrantedOptimismException((double)x + 1, programPoint);
         }
     }
 
     /**
      * Wrapper for negateExact

@@ -1811,32 +1573,10 @@
             if (x == 0) {
                 throw new UnwarrantedOptimismException(-0.0, programPoint);
             }
             return Math.negateExact(x);
         } catch (final ArithmeticException e) {
-            throw new UnwarrantedOptimismException(-(long)x, programPoint);
-        }
-    }
-
-    /**
-     * Wrapper for negateExact
-     *
-     * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
-     * containing the result and the program point of the failure
-     *
-     * @param x the number to negate
-     * @param programPoint program point id
-     * @return the result
-     * @throws UnwarrantedOptimismException if overflow occurs
-     */
-    public static long negateExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
-        try {
-            if (x == 0L) {
-                throw new UnwarrantedOptimismException(-0.0, programPoint);
-            }
-            return Math.negateExact(x);
-        } catch (final ArithmeticException e) {
             throw new UnwarrantedOptimismException(-(double)x, programPoint);
         }
     }
 
     /**

@@ -1864,12 +1604,10 @@
     public static int getAccessorTypeIndex(final Class<?> type) {
         if (type == null) {
             return TYPE_UNDEFINED_INDEX;
         } else if (type == int.class) {
             return TYPE_INT_INDEX;
-        } else if (type == long.class) {
-            return TYPE_LONG_INDEX;
         } else if (type == double.class) {
             return TYPE_DOUBLE_INDEX;
         } else if (!type.isPrimitive()) {
             return TYPE_OBJECT_INDEX;
         }

@@ -1970,12 +1708,10 @@
      * @return the boxed type of clazz, or unchanged if not primitive
      */
     public static Class<?> getBoxedClass(final Class<?> clazz) {
         if (clazz == int.class) {
             return Integer.class;
-        } else if (clazz == long.class) {
-            return Long.class;
         } else if (clazz == double.class) {
             return Double.class;
         }
         assert !clazz.isPrimitive();
         return clazz;

@@ -1989,12 +1725,10 @@
      */
     public static MethodHandle unboxConstant(final Object o) {
         if (o != null) {
             if (o.getClass() == Integer.class) {
                 return MH.constant(int.class, ((Integer)o));
-            } else if (o.getClass() == Long.class) {
-                return MH.constant(long.class, ((Long)o));
             } else if (o.getClass() == Double.class) {
                 return MH.constant(double.class, ((Double)o));
             }
         }
         return MH.constant(Object.class, o);

@@ -2008,12 +1742,10 @@
     public static Class<?> unboxedFieldType(final Object o) {
         if (o == null) {
             return Object.class;
         } else if (o.getClass() == Integer.class) {
             return int.class;
-        } else if (o.getClass() == Long.class) {
-            return long.class;
         } else if (o.getClass() == Double.class) {
             return double.class;
         } else {
             return Object.class;
         }
< prev index next >