< prev index next >

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

Print this page




 102 
 103     /** JavaScript compliant conversion function from Object to number with type check */
 104     public static final Call TO_NUMBER_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toNumberOptimistic", double.class, Object.class, int.class);
 105 
 106     /** JavaScript compliant conversion function from Object to String */
 107     public static final Call TO_STRING = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, Object.class);
 108 
 109     /** JavaScript compliant conversion function from Object to int32 */
 110     public static final Call TO_INT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, Object.class);
 111 
 112     /** JavaScript compliant conversion function from Object to int32 */
 113     public static final Call TO_INT32_L = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, long.class);
 114 
 115     /** JavaScript compliant conversion function from Object to int32 with type check */
 116     public static final Call TO_INT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32Optimistic", int.class, Object.class, int.class);
 117 
 118     /** JavaScript compliant conversion function from double to int32 */
 119     public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class);
 120 
 121     /** JavaScript compliant conversion function from int to uint32 */
 122     public static final Call TO_UINT32_I = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, int.class);



 123 
 124     /** JavaScript compliant conversion function from Object to uint32 */
 125     public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class);
 126 
 127     /** JavaScript compliant conversion function from Object to long with type check */
 128     public static final Call TO_LONG_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toLongOptimistic", long.class, Object.class, int.class);
 129 
 130     /** JavaScript compliant conversion function from number to uint32 */
 131     public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class);
 132 
 133     /** JavaScript compliant conversion function from number to String */
 134     public static final Call TO_STRING_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, double.class);
 135 
 136     /** Combined call to toPrimitive followed by toString. */
 137     public static final Call TO_PRIMITIVE_TO_STRING = staticCall(JSTYPE_LOOKUP, JSType.class, "toPrimitiveToString", String.class, Object.class);
 138 
 139     /** Combined call to toPrimitive followed by toCharSequence. */
 140     public static final Call TO_PRIMITIVE_TO_CHARSEQUENCE = staticCall(JSTYPE_LOOKUP, JSType.class, "toPrimitiveToCharSequence", CharSequence.class, Object.class);
 141 
 142     /** Throw an unwarranted optimism exception */
 143     public static final Call THROW_UNWARRANTED = staticCall(JSTYPE_LOOKUP, JSType.class, "throwUnwarrantedOptimismException", Object.class, Object.class, int.class);
 144 
 145     /** Add exact wrapper for potentially overflowing integer operations */
 146     public static final Call ADD_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", int.class, int.class, int.class, int.class);
 147 
 148     /** Sub exact wrapper for potentially overflowing integer operations */
 149     public static final Call SUB_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", int.class, int.class, int.class, int.class);


 155     public static final Call DIV_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", int.class, int.class, int.class, int.class);
 156 
 157     /** Div zero wrapper for integer division that handles (0/0)|0 == 0 */
 158     public static final Call DIV_ZERO        = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", int.class, int.class, int.class);
 159 
 160     /** Mod zero wrapper for integer division that handles (0%0)|0 == 0 */
 161     public static final Call REM_ZERO        = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", int.class, int.class, int.class);
 162 
 163     /** Mod exact wrapper for potentially integer remainders that turns into float point */
 164     public static final Call REM_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", int.class, int.class, int.class, int.class);
 165 
 166     /** Decrement exact wrapper for potentially overflowing integer operations */
 167     public static final Call DECREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact",   int.class, int.class, int.class);
 168 
 169     /** Increment exact wrapper for potentially overflowing integer operations */
 170     public static final Call INCREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact",   int.class, int.class, int.class);
 171 
 172     /** Negate exact exact wrapper for potentially overflowing integer operations */
 173     public static final Call NEGATE_EXACT         = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", int.class, int.class, int.class);
 174 
 175     /** Add exact wrapper for potentially overflowing long operations */
 176     public static final Call ADD_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", long.class, long.class, long.class, int.class);
 177 
 178     /** Sub exact wrapper for potentially overflowing long operations */
 179     public static final Call SUB_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", long.class, long.class, long.class, int.class);
 180 
 181     /** Multiply exact wrapper for potentially overflowing long operations */
 182     public static final Call MUL_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "mulExact", long.class, long.class, long.class, int.class);
 183 
 184     /** Div exact wrapper for potentially integer division that turns into float point */
 185     public static final Call DIV_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class);
 186 
 187     /** Div zero wrapper for long division that handles (0/0) &gt;&gt;&gt; 0 == 0 */
 188     public static final Call DIV_ZERO_LONG        = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class);
 189 
 190     /** Mod zero wrapper for long division that handles (0%0) &gt;&gt;&gt; 0 == 0 */
 191     public static final Call REM_ZERO_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class);
 192 
 193     /** Mod exact wrapper for potentially integer remainders that turns into float point */
 194     public static final Call REM_EXACT_LONG       = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", long.class, long.class, long.class, int.class);
 195 
 196     /** Decrement exact wrapper for potentially overflowing long operations */
 197     public static final Call DECREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact",  long.class, long.class, int.class);
 198 
 199     /** Increment exact wrapper for potentially overflowing long operations */
 200     public static final Call INCREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact",  long.class, long.class, int.class);
 201 
 202     /** Negate exact exact wrapper for potentially overflowing long operations */
 203     public static final Call NEGATE_EXACT_LONG    = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact",     long.class, long.class, int.class);
 204 
 205     /** Method handle to convert a JS Object to a Java array. */
 206     public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
 207 
 208     /** Method handle for void returns. */
 209     public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class);
 210 
 211     /**
 212      * The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
 213      *  in the dual--fields world
 214      */
 215     private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
 216             Arrays.asList(
 217                 Type.INT,
 218                 Type.LONG,
 219                 Type.NUMBER,
 220                 Type.OBJECT));
 221 
 222     /** table index for undefined type - hard coded so it can be used in switches at compile time */
 223     public static final int TYPE_UNDEFINED_INDEX = -1;
 224     /** table index for integer type - hard coded so it can be used in switches at compile time */
 225     public static final int TYPE_INT_INDEX    = 0; //getAccessorTypeIndex(int.class);
 226     /** table index for long type - hard coded so it can be used in switches at compile time */
 227     public static final int TYPE_LONG_INDEX   = 1; //getAccessorTypeIndex(long.class);
 228     /** table index for double type - hard coded so it can be used in switches at compile time */
 229     public static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
 230     /** table index for object type - hard coded so it can be used in switches at compile time */
 231     public static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
 232 
 233     /** object conversion quickies with JS semantics - used for return value and parameter filter */
 234     public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList(
 235         JSType.TO_INT32.methodHandle(),
 236         JSType.TO_UINT32.methodHandle(),
 237         JSType.TO_NUMBER.methodHandle(),
 238         null
 239     );
 240 
 241     /**
 242      * object conversion quickies with JS semantics - used for return value and parameter filter, optimistic
 243      * throws exception upon incompatible type (asking for a narrower one than the storage)
 244      */
 245     public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList(
 246         JSType.TO_INT32_OPTIMISTIC.methodHandle(),
 247         JSType.TO_LONG_OPTIMISTIC.methodHandle(),
 248         JSType.TO_NUMBER_OPTIMISTIC.methodHandle(),
 249         null
 250     );
 251 
 252     /** The value of Undefined cast to an int32 */
 253     public static final int    UNDEFINED_INT    = 0;
 254     /** The value of Undefined cast to a long */
 255     public static final long   UNDEFINED_LONG   = 0L;
 256     /** The value of Undefined cast to a double */
 257     public static final double UNDEFINED_DOUBLE = Double.NaN;
 258 




 259     /**
 260      * Method handles for getters that return undefined coerced
 261      * to the appropriate type
 262      */
 263     public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList(
 264         MH.constant(int.class, UNDEFINED_INT),
 265         MH.constant(long.class, UNDEFINED_LONG),
 266         MH.constant(double.class, UNDEFINED_DOUBLE),
 267         MH.constant(Object.class, Undefined.getUndefined())
 268     );
 269 
 270     private static final double INT32_LIMIT = 4294967296.0;
 271 
 272     /**
 273      * Constructor
 274      *
 275      * @param typeName the type name
 276      */
 277     private JSType(final String typeName) {
 278         this.typeName = typeName;
 279     }
 280 
 281     /**
 282      * The external type name as returned by ECMAScript "typeof" operator
 283      *
 284      * @return type name for this type
 285      */


 411     public static boolean isStrictlyRepresentableAsInt(final double number) {
 412         return isRepresentableAsInt(number) && isNotNegativeZero(number);
 413     }
 414 
 415     /**
 416      * Returns true if Object can be represented as an int
 417      *
 418      * @param obj an object to inspect
 419      *
 420      * @return true for int representable objects
 421      */
 422     public static boolean isRepresentableAsInt(final Object obj) {
 423         if (obj instanceof Number) {
 424             return isRepresentableAsInt(((Number)obj).doubleValue());
 425         }
 426         return false;
 427     }
 428 
 429     /**
 430      * Returns true if double number can be represented as a long. Note that it returns true for negative
 431      * zero. If you need to exclude negative zero, use {@link #isStrictlyRepresentableAsLong(double)}.
 432      *
 433      * @param number a double to inspect
 434      * @return true for long representable doubles
 435      */
 436     public static boolean isRepresentableAsLong(final double number) {
 437         return (long)number == number;
 438     }
 439 
 440     /**
 441      * Returns true if double number can be represented as a long. Note that it returns false for negative
 442      * zero. If you don't need to distinguish negative zero, use {@link #isRepresentableAsLong(double)}.
 443      *
 444      * @param number a double to inspect
 445      *
 446      * @return true for long representable doubles
 447      */
 448     public static boolean isStrictlyRepresentableAsLong(final double number) {
 449         return isRepresentableAsLong(number) && isNotNegativeZero(number);
 450     }
 451 
 452     /**
 453      * Returns true if Object can be represented as a long
 454      *
 455      * @param obj an object to inspect
 456      *
 457      * @return true for long representable objects
 458      */
 459     public static boolean isRepresentableAsLong(final Object obj) {
 460         if (obj instanceof Number) {
 461             return isRepresentableAsLong(((Number)obj).doubleValue());
 462         }
 463         return false;
 464     }
 465 
 466     /**
 467      * Returns true if the number is not the negative zero ({@code -0.0d}).
 468      * @param number the number to test
 469      * @return true if it is not the negative zero, false otherwise.
 470      */
 471     private static boolean isNotNegativeZero(final double number) {
 472         return Double.doubleToRawLongBits(number) != 0x8000000000000000L;
 473     }
 474 
 475     /**
 476      * Check whether an object is primitive
 477      *
 478      * @param obj an object
 479      *
 480      * @return true if object is primitive (includes null and undefined)
 481      */
 482     public static boolean isPrimitive(final Object obj) {
 483         return obj == null ||


 633      */
 634     public static Object toPropertyKey(final Object obj) {
 635         return obj instanceof Symbol ? obj : toStringImpl(obj, false);
 636     }
 637 
 638     /**
 639      * If obj is an instance of {@link ConsString} cast to CharSequence, else return
 640      * result of {@link #toString(Object)}.
 641      *
 642      * @param obj an object
 643      * @return an instance of String or ConsString
 644      */
 645     public static CharSequence toCharSequence(final Object obj) {
 646         if (obj instanceof ConsString) {
 647             return (CharSequence) obj;
 648         }
 649         return toString(obj);
 650     }
 651 
 652     /**
 653      * Check whether a string is representable as a JavaScript number
 654      *
 655      * @param str  a string
 656      *
 657      * @return     true if string can be represented as a number
 658      */
 659     public static boolean isNumber(final String str) {
 660         try {
 661             Double.parseDouble(str);
 662             return true;
 663         } catch (final NumberFormatException e) {
 664             return false;
 665         }
 666     }
 667 
 668     /**
 669      * Returns true if object represents a primitive JavaScript string value.
 670      * @param obj the object
 671      * @return true if the object represents a primitive JavaScript string value.
 672      */
 673     public static boolean isString(final Object obj) {
 674         return obj instanceof String || obj instanceof ConsString;
 675     }
 676 
 677     /**
 678      * JavaScript compliant conversion of integer to String
 679      *
 680      * @param num an integer
 681      *
 682      * @return a string
 683      */
 684     public static String toString(final int num) {
 685         return Integer.toString(num);
 686     }
 687 
 688     /**


1016      * caller's responsibility to handle such values correctly.</p>
1017      *
1018      * @param obj  an object
1019      * @return a long
1020      */
1021     public static long toLong(final Object obj) {
1022         return obj instanceof Long ? ((Long)obj) : toLong(toNumber(obj));
1023     }
1024 
1025     /**
1026      * Converts a double to long.
1027      *
1028      * @param num the double to convert
1029      * @return the converted long value
1030      */
1031     public static long toLong(final double num) {
1032         return (long)num;
1033     }
1034 
1035     /**
1036      * Optimistic long conversion - throws UnwarrantedOptimismException if double or Object
1037      *
1038      * @param obj           object to convert
1039      * @param programPoint  program point
1040      * @return long
1041      */
1042     public static long toLongOptimistic(final Object obj, final int programPoint) {
1043         if (obj != null) {
1044             final Class<?> clz = obj.getClass();
1045             if (clz == Long.class || clz == Integer.class) {
1046                 return ((Number)obj).longValue();
1047             }
1048         }
1049         throw new UnwarrantedOptimismException(obj, programPoint);
1050     }
1051 
1052     /**
1053      * Object to int conversion that delegates to either {@link #toLong(Object)} or to
1054      * {@link #toLongOptimistic(Object, int)} depending on whether the program point is valid or not.
1055      * @param obj the object to convert
1056      * @param programPoint the program point; can be invalid.
1057      * @return the value converted to long
1058      * @throws UnwarrantedOptimismException if the value can't be represented as long and the program point is valid.
1059      */
1060     public static long toLongMaybeOptimistic(final Object obj, final int programPoint) {
1061         return UnwarrantedOptimismException.isValid(programPoint) ? toLongOptimistic(obj, programPoint) : toLong(obj);
1062     }
1063 
1064     /**
1065      * JavaScript compliant Object to int32 conversion
1066      * See ECMA 9.5 ToInt32
1067      *
1068      * @param obj an object
1069      * @return an int32
1070      */
1071     public static int toInt32(final Object obj) {
1072         return toInt32(toNumber(obj));
1073     }
1074 
1075     /**
1076      * Optimistic int conversion - throws UnwarrantedOptimismException if double, long or Object
1077      *
1078      * @param obj           object to convert
1079      * @param programPoint  program point
1080      * @return double
1081      */
1082     public static int toInt32Optimistic(final Object obj, final int programPoint) {
1083         if (obj != null && obj.getClass() == Integer.class) {
1084             return ((Integer)obj);
1085         }
1086         throw new UnwarrantedOptimismException(obj, programPoint);
1087     }
1088 
1089     /**
1090      * Object to int conversion that delegates to either {@link #toInt32(Object)} or to
1091      * {@link #toInt32Optimistic(Object, int)} depending on whether the program point is valid or not.
1092      * @param obj the object to convert
1093      * @param programPoint the program point; can be invalid.
1094      * @return the value converted to int
1095      * @throws UnwarrantedOptimismException if the value can't be represented as int and the program point is valid.
1096      */
1097     public static int toInt32MaybeOptimistic(final Object obj, final int programPoint) {
1098         return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj);
1099     }
1100 
1101     // Minimum and maximum range between which every long value can be precisely represented as a double.
1102     private static final long MAX_PRECISE_DOUBLE = 1L << 53;
1103     private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
1104 
1105     /**
1106      * JavaScript compliant long to int32 conversion
1107      *
1108      * @param num a long
1109      * @return an int32
1110      */
1111     public static int toInt32(final long num) {
1112         return (int)(num >= MIN_PRECISE_DOUBLE && num <= MAX_PRECISE_DOUBLE ? num : (long)(num % INT32_LIMIT));
1113     }
1114 
1115 
1116     /**
1117      * JavaScript compliant number to int32 conversion
1118      *
1119      * @param num a number
1120      * @return an int32
1121      */
1122     public static int toInt32(final double num) {
1123         return (int)doubleToInt32(num);
1124     }


1137      * JavaScript compliant number to uint32 conversion
1138      *
1139      * @param num a number
1140      * @return a uint32
1141      */
1142     public static long toUint32(final double num) {
1143         return doubleToInt32(num) & MAX_UINT;
1144     }
1145 
1146     /**
1147      * JavaScript compliant int to uint32 conversion
1148      *
1149      * @param num an int
1150      * @return a uint32
1151      */
1152     public static long toUint32(final int num) {
1153         return num & MAX_UINT;
1154     }
1155 
1156     /**























1157      * JavaScript compliant Object to uint16 conversion
1158      * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
1159      *
1160      * @param obj an object
1161      * @return a uint16
1162      */
1163     public static int toUint16(final Object obj) {
1164         return toUint16(toNumber(obj));
1165     }
1166 
1167     /**
1168      * JavaScript compliant number to uint16 conversion
1169      *
1170      * @param num a number
1171      * @return a uint16
1172      */
1173     public static int toUint16(final int num) {
1174         return num & 0xffff;
1175     }
1176 


1467     private static Object throwUnwarrantedOptimismException(final Object value, final int programPoint) {
1468         throw new UnwarrantedOptimismException(value, programPoint);
1469     }
1470 
1471     /**
1472      * Wrapper for addExact
1473      *
1474      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1475      * containing the result and the program point of the failure
1476      *
1477      * @param x first term
1478      * @param y second term
1479      * @param programPoint program point id
1480      * @return the result
1481      * @throws UnwarrantedOptimismException if overflow occurs
1482      */
1483     public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1484         try {
1485             return Math.addExact(x, y);
1486         } catch (final ArithmeticException e) {
1487             throw new UnwarrantedOptimismException((long)x + (long)y, programPoint);
1488         }
1489     }
1490 
1491     /**
1492      * Wrapper for addExact
1493      *
1494      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1495      * containing the result and the program point of the failure
1496      *
1497      * @param x first term
1498      * @param y second term
1499      * @param programPoint program point id
1500      * @return the result
1501      * @throws UnwarrantedOptimismException if overflow occurs
1502      */
1503     public static long addExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1504         try {
1505             return Math.addExact(x, y);
1506         } catch (final ArithmeticException e) {
1507             throw new UnwarrantedOptimismException((double)x + (double)y, programPoint);
1508         }
1509     }
1510 
1511     /**
1512      * Wrapper for subExact
1513      *
1514      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1515      * containing the result and the program point of the failure
1516      *
1517      * @param x first term
1518      * @param y second term
1519      * @param programPoint program point id
1520      * @return the result
1521      * @throws UnwarrantedOptimismException if overflow occurs
1522      */
1523     public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1524         try {
1525             return Math.subtractExact(x, y);
1526         } catch (final ArithmeticException e) {
1527             throw new UnwarrantedOptimismException((long)x - (long)y, programPoint);
1528         }
1529     }
1530 
1531     /**
1532      * Wrapper for subExact
1533      *
1534      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1535      * containing the result and the program point of the failure
1536      *
1537      * @param x first term
1538      * @param y second term
1539      * @param programPoint program point id
1540      * @return the result
1541      * @throws UnwarrantedOptimismException if overflow occurs
1542      */
1543     public static long subExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1544         try {
1545             return Math.subtractExact(x, y);
1546         } catch (final ArithmeticException e) {
1547             throw new UnwarrantedOptimismException((double)x - (double)y, programPoint);
1548         }
1549     }
1550 
1551     /**
1552      * Wrapper for mulExact
1553      *
1554      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1555      * containing the result and the program point of the failure
1556      *
1557      * @param x first term
1558      * @param y second term
1559      * @param programPoint program point id
1560      * @return the result
1561      * @throws UnwarrantedOptimismException if overflow occurs
1562      */
1563     public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1564         try {
1565             return Math.multiplyExact(x, y);
1566         } catch (final ArithmeticException e) {
1567             throw new UnwarrantedOptimismException((long)x * (long)y, programPoint);
1568         }
1569     }
1570 
1571     /**
1572      * Wrapper for mulExact
1573      *
1574      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1575      * containing the result and the program point of the failure
1576      *
1577      * @param x first term
1578      * @param y second term
1579      * @param programPoint program point id
1580      * @return the result
1581      * @throws UnwarrantedOptimismException if overflow occurs
1582      */
1583     public static long mulExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1584         try {
1585             return Math.multiplyExact(x, y);
1586         } catch (final ArithmeticException e) {
1587             throw new UnwarrantedOptimismException((double)x * (double)y, programPoint);
1588         }
1589     }
1590 
1591     /**
1592      * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
1593      * int.
1594      *
1595      * @param x first term
1596      * @param y second term
1597      * @param programPoint program point id
1598      * @return the result
1599      * @throws UnwarrantedOptimismException if the result of the division can't be represented as int.
1600      */
1601     public static int divExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1602         final int res;
1603         try {
1604             res = x / y;
1605         } catch (final ArithmeticException e) {
1606             assert y == 0; // Only div by zero anticipated


1638 
1639     /**
1640      * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
1641      *
1642      * @param x first term
1643      * @param y second term
1644      * @param programPoint program point id
1645      * @return the result
1646      * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
1647      */
1648     public static int remExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1649         try {
1650             return x % y;
1651         } catch (final ArithmeticException e) {
1652             assert y == 0; // Only mod by zero anticipated
1653             throw new UnwarrantedOptimismException(Double.NaN, programPoint);
1654         }
1655     }
1656 
1657     /**
1658      * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
1659      * long.
1660      *
1661      * @param x first term
1662      * @param y second term
1663      * @param programPoint program point id
1664      * @return the result
1665      * @throws UnwarrantedOptimismException if the result of the division can't be represented as long.
1666      */
1667     public static long divExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1668         final long res;
1669         try {
1670             res = x / y;
1671         } catch (final ArithmeticException e) {
1672             assert y == 0L; // Only div by zero anticipated
1673             throw new UnwarrantedOptimismException(x > 0L ? Double.POSITIVE_INFINITY : x < 0L ? Double.NEGATIVE_INFINITY : Double.NaN, programPoint);
1674         }
1675         final long rem = x % y;
1676         if (rem == 0L) {
1677             return res;
1678         }
1679         throw new UnwarrantedOptimismException((double)x / (double)y, programPoint);
1680     }
1681 
1682     /**
1683      * Implements long division but allows {@code x / 0} to be represented as 0. Useful when division of two longs
1684      * is coerced to long.
1685      * @param x the dividend
1686      * @param y the divisor
1687      * @return the result
1688      */
1689     public static long divZero(final long x, final long y) {
1690         return y == 0L ? 0L : x / y;
1691     }
1692 
1693     /**
1694      * Implements long remainder but allows {@code x % 0} to be represented as 0. Useful when remainder of two longs
1695      * is coerced to long.
1696      * @param x the dividend
1697      * @param y the divisor
1698      * @return the remainder
1699      */
1700     public static long remZero(final long x, final long y) {
1701         return y == 0L ? 0L : x % y;
1702     }
1703 
1704     /**
1705      * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
1706      *
1707      * @param x first term
1708      * @param y second term
1709      * @param programPoint program point id
1710      * @return the result
1711      * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
1712      */
1713     public static long remExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1714         try {
1715             return x % y;
1716         } catch (final ArithmeticException e) {
1717             assert y == 0L; // Only mod by zero anticipated
1718             throw new UnwarrantedOptimismException(Double.NaN, programPoint);
1719         }
1720     }
1721 
1722     /**
1723      * Wrapper for decrementExact
1724      *
1725      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1726      * containing the result and the program point of the failure
1727      *
1728      * @param x number to negate
1729      * @param programPoint program point id
1730      * @return the result
1731      * @throws UnwarrantedOptimismException if overflow occurs
1732      */
1733     public static int decrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1734         try {
1735             return Math.decrementExact(x);
1736         } catch (final ArithmeticException e) {
1737             throw new UnwarrantedOptimismException((long)x - 1, programPoint);
1738         }
1739     }
1740 
1741     /**
1742      * Wrapper for decrementExact
1743      *
1744      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1745      * containing the result and the program point of the failure
1746      *
1747      * @param x number to negate
1748      * @param programPoint program point id
1749      * @return the result
1750      * @throws UnwarrantedOptimismException if overflow occurs
1751      */
1752     public static long decrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
1753         try {
1754             return Math.decrementExact(x);
1755         } catch (final ArithmeticException e) {
1756             throw new UnwarrantedOptimismException((double)x - 1L, programPoint);
1757         }
1758     }
1759 
1760     /**
1761      * Wrapper for incrementExact
1762      *
1763      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1764      * containing the result and the program point of the failure
1765      *
1766      * @param x the number to increment
1767      * @param programPoint program point id
1768      * @return the result
1769      * @throws UnwarrantedOptimismException if overflow occurs
1770      */
1771     public static int incrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1772         try {
1773             return Math.incrementExact(x);
1774         } catch (final ArithmeticException e) {
1775             throw new UnwarrantedOptimismException((long)x + 1, programPoint);
1776         }
1777     }
1778 
1779     /**
1780      * Wrapper for incrementExact
1781      *
1782      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1783      * containing the result and the program point of the failure
1784      *
1785      * @param x the number to increment
1786      * @param programPoint program point id
1787      * @return the result
1788      * @throws UnwarrantedOptimismException if overflow occurs
1789      */
1790     public static long incrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
1791         try {
1792             return Math.incrementExact(x);
1793         } catch (final ArithmeticException e) {
1794             throw new UnwarrantedOptimismException((double)x + 1L, programPoint);
1795         }
1796     }
1797 
1798     /**
1799      * Wrapper for negateExact
1800      *
1801      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1802      * containing the result and the program point of the failure
1803      *
1804      * @param x the number to negate
1805      * @param programPoint program point id
1806      * @return the result
1807      * @throws UnwarrantedOptimismException if overflow occurs
1808      */
1809     public static int negateExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1810         try {
1811             if (x == 0) {
1812                 throw new UnwarrantedOptimismException(-0.0, programPoint);
1813             }
1814             return Math.negateExact(x);
1815         } catch (final ArithmeticException e) {
1816             throw new UnwarrantedOptimismException(-(long)x, programPoint);
1817         }
1818     }
1819 
1820     /**
1821      * Wrapper for negateExact
1822      *
1823      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1824      * containing the result and the program point of the failure
1825      *
1826      * @param x the number to negate
1827      * @param programPoint program point id
1828      * @return the result
1829      * @throws UnwarrantedOptimismException if overflow occurs
1830      */
1831     public static long negateExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
1832         try {
1833             if (x == 0L) {
1834                 throw new UnwarrantedOptimismException(-0.0, programPoint);
1835             }
1836             return Math.negateExact(x);
1837         } catch (final ArithmeticException e) {
1838             throw new UnwarrantedOptimismException(-(double)x, programPoint);
1839         }
1840     }
1841 
1842     /**
1843      * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
1844      *
1845      * @param type the type
1846      *
1847      * @return the accessor index, or -1 if no accessor of this type exists
1848      */
1849     public static int getAccessorTypeIndex(final Type type) {
1850         return getAccessorTypeIndex(type.getTypeClass());
1851     }
1852 
1853     /**
1854      * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
1855      *
1856      * Note that this is hardcoded with respect to the dynamic contents of the accessor
1857      * types array for speed. Hotspot got stuck with this as 5% of the runtime in
1858      * a benchmark when it looped over values and increased an index counter. :-(
1859      *
1860      * @param type the type
1861      *
1862      * @return the accessor index, or -1 if no accessor of this type exists
1863      */
1864     public static int getAccessorTypeIndex(final Class<?> type) {
1865         if (type == null) {
1866             return TYPE_UNDEFINED_INDEX;
1867         } else if (type == int.class) {
1868             return TYPE_INT_INDEX;
1869         } else if (type == long.class) {
1870             return TYPE_LONG_INDEX;
1871         } else if (type == double.class) {
1872             return TYPE_DOUBLE_INDEX;
1873         } else if (!type.isPrimitive()) {
1874             return TYPE_OBJECT_INDEX;
1875         }
1876         return -1;
1877     }
1878 
1879     /**
1880      * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
1881      * Indexes are ordered narrower{@literal ->}wider / optimistic{@literal ->}pessimistic. Invalidations always
1882      * go to a type of higher index
1883      *
1884      * @param index accessor type index
1885      *
1886      * @return a type corresponding to the index.
1887      */
1888 
1889     public static Type getAccessorType(final int index) {
1890         return ACCESSOR_TYPES.get(index);


1955     }
1956 
1957     private static Object invoke(final MethodHandle mh, final Object arg) {
1958         try {
1959             return mh.invoke(arg);
1960         } catch (final RuntimeException | Error e) {
1961             throw e;
1962         } catch (final Throwable t) {
1963             throw new RuntimeException(t);
1964         }
1965     }
1966 
1967     /**
1968      * Returns the boxed version of a primitive class
1969      * @param clazz the class
1970      * @return the boxed type of clazz, or unchanged if not primitive
1971      */
1972     public static Class<?> getBoxedClass(final Class<?> clazz) {
1973         if (clazz == int.class) {
1974             return Integer.class;
1975         } else if (clazz == long.class) {
1976             return Long.class;
1977         } else if (clazz == double.class) {
1978             return Double.class;
1979         }
1980         assert !clazz.isPrimitive();
1981         return clazz;
1982     }
1983 
1984     /**
1985      * Create a method handle constant of the correct primitive type
1986      * for a constant object
1987      * @param o object
1988      * @return constant function that returns object
1989      */
1990     public static MethodHandle unboxConstant(final Object o) {
1991         if (o != null) {
1992             if (o.getClass() == Integer.class) {
1993                 return MH.constant(int.class, ((Integer)o));
1994             } else if (o.getClass() == Long.class) {
1995                 return MH.constant(long.class, ((Long)o));
1996             } else if (o.getClass() == Double.class) {
1997                 return MH.constant(double.class, ((Double)o));
1998             }
1999         }
2000         return MH.constant(Object.class, o);
2001     }
2002 
2003     /**
2004      * Get the unboxed (primitive) type for an object
2005      * @param o object
2006      * @return primitive type or Object.class if not primitive
2007      */
2008     public static Class<?> unboxedFieldType(final Object o) {
2009         if (o == null) {
2010             return Object.class;
2011         } else if (o.getClass() == Integer.class) {
2012             return int.class;
2013         } else if (o.getClass() == Long.class) {
2014             return long.class;
2015         } else if (o.getClass() == Double.class) {
2016             return double.class;
2017         } else {
2018             return Object.class;
2019         }
2020     }
2021 
2022     private static List<MethodHandle> toUnmodifiableList(final MethodHandle... methodHandles) {
2023         return Collections.unmodifiableList(Arrays.asList(methodHandles));
2024     }
2025 }


 102 
 103     /** JavaScript compliant conversion function from Object to number with type check */
 104     public static final Call TO_NUMBER_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toNumberOptimistic", double.class, Object.class, int.class);
 105 
 106     /** JavaScript compliant conversion function from Object to String */
 107     public static final Call TO_STRING = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, Object.class);
 108 
 109     /** JavaScript compliant conversion function from Object to int32 */
 110     public static final Call TO_INT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, Object.class);
 111 
 112     /** JavaScript compliant conversion function from Object to int32 */
 113     public static final Call TO_INT32_L = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, long.class);
 114 
 115     /** JavaScript compliant conversion function from Object to int32 with type check */
 116     public static final Call TO_INT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32Optimistic", int.class, Object.class, int.class);
 117 
 118     /** JavaScript compliant conversion function from double to int32 */
 119     public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class);
 120 
 121     /** JavaScript compliant conversion function from int to uint32 */
 122     public static final Call TO_UINT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Optimistic", int.class, int.class, int.class);
 123 
 124     /** JavaScript compliant conversion function from int to uint32 */
 125     public static final Call TO_UINT32_DOUBLE = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Double", double.class, int.class);
 126 
 127     /** JavaScript compliant conversion function from Object to uint32 */
 128     public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class);
 129 



 130     /** JavaScript compliant conversion function from number to uint32 */
 131     public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class);
 132 
 133     /** JavaScript compliant conversion function from number to String */
 134     public static final Call TO_STRING_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toString", String.class, double.class);
 135 
 136     /** Combined call to toPrimitive followed by toString. */
 137     public static final Call TO_PRIMITIVE_TO_STRING = staticCall(JSTYPE_LOOKUP, JSType.class, "toPrimitiveToString", String.class, Object.class);
 138 
 139     /** Combined call to toPrimitive followed by toCharSequence. */
 140     public static final Call TO_PRIMITIVE_TO_CHARSEQUENCE = staticCall(JSTYPE_LOOKUP, JSType.class, "toPrimitiveToCharSequence", CharSequence.class, Object.class);
 141 
 142     /** Throw an unwarranted optimism exception */
 143     public static final Call THROW_UNWARRANTED = staticCall(JSTYPE_LOOKUP, JSType.class, "throwUnwarrantedOptimismException", Object.class, Object.class, int.class);
 144 
 145     /** Add exact wrapper for potentially overflowing integer operations */
 146     public static final Call ADD_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", int.class, int.class, int.class, int.class);
 147 
 148     /** Sub exact wrapper for potentially overflowing integer operations */
 149     public static final Call SUB_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", int.class, int.class, int.class, int.class);


 155     public static final Call DIV_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", int.class, int.class, int.class, int.class);
 156 
 157     /** Div zero wrapper for integer division that handles (0/0)|0 == 0 */
 158     public static final Call DIV_ZERO        = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", int.class, int.class, int.class);
 159 
 160     /** Mod zero wrapper for integer division that handles (0%0)|0 == 0 */
 161     public static final Call REM_ZERO        = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", int.class, int.class, int.class);
 162 
 163     /** Mod exact wrapper for potentially integer remainders that turns into float point */
 164     public static final Call REM_EXACT       = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", int.class, int.class, int.class, int.class);
 165 
 166     /** Decrement exact wrapper for potentially overflowing integer operations */
 167     public static final Call DECREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact",   int.class, int.class, int.class);
 168 
 169     /** Increment exact wrapper for potentially overflowing integer operations */
 170     public static final Call INCREMENT_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact",   int.class, int.class, int.class);
 171 
 172     /** Negate exact exact wrapper for potentially overflowing integer operations */
 173     public static final Call NEGATE_EXACT         = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", int.class, int.class, int.class);
 174 






























 175     /** Method handle to convert a JS Object to a Java array. */
 176     public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
 177 
 178     /** Method handle for void returns. */
 179     public static final Call VOID_RETURN = staticCall(JSTYPE_LOOKUP, JSType.class, "voidReturn", void.class);
 180 
 181     /**
 182      * The list of available accessor types in width order. This order is used for type guesses narrow{@literal ->} wide
 183      *  in the dual--fields world
 184      */
 185     private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
 186             Arrays.asList(
 187                 Type.INT,

 188                 Type.NUMBER,
 189                 Type.OBJECT));
 190 
 191     /** table index for undefined type - hard coded so it can be used in switches at compile time */
 192     public static final int TYPE_UNDEFINED_INDEX = -1;
 193     /** table index for integer type - hard coded so it can be used in switches at compile time */
 194     public static final int TYPE_INT_INDEX    = 0; //getAccessorTypeIndex(int.class);


 195     /** table index for double type - hard coded so it can be used in switches at compile time */
 196     public static final int TYPE_DOUBLE_INDEX = 1; //getAccessorTypeIndex(double.class);
 197     /** table index for object type - hard coded so it can be used in switches at compile time */
 198     public static final int TYPE_OBJECT_INDEX = 2; //getAccessorTypeIndex(Object.class);
 199 
 200     /** object conversion quickies with JS semantics - used for return value and parameter filter */
 201     public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList(
 202         JSType.TO_INT32.methodHandle(),

 203         JSType.TO_NUMBER.methodHandle(),
 204         null
 205     );
 206 
 207     /**
 208      * object conversion quickies with JS semantics - used for return value and parameter filter, optimistic
 209      * throws exception upon incompatible type (asking for a narrower one than the storage)
 210      */
 211     public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList(
 212         JSType.TO_INT32_OPTIMISTIC.methodHandle(),

 213         JSType.TO_NUMBER_OPTIMISTIC.methodHandle(),
 214         null
 215     );
 216 
 217     /** The value of Undefined cast to an int32 */
 218     public static final int    UNDEFINED_INT    = 0;
 219     /** The value of Undefined cast to a long */
 220     public static final long   UNDEFINED_LONG   = 0L;
 221     /** The value of Undefined cast to a double */
 222     public static final double UNDEFINED_DOUBLE = Double.NaN;
 223 
 224     // Minimum and maximum range between which every long value can be precisely represented as a double.
 225     private static final long MAX_PRECISE_DOUBLE = 1L << 53;
 226     private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
 227 
 228     /**
 229      * Method handles for getters that return undefined coerced
 230      * to the appropriate type
 231      */
 232     public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList(
 233         MH.constant(int.class, UNDEFINED_INT),

 234         MH.constant(double.class, UNDEFINED_DOUBLE),
 235         MH.constant(Object.class, Undefined.getUndefined())
 236     );
 237 
 238     private static final double INT32_LIMIT = 4294967296.0;
 239 
 240     /**
 241      * Constructor
 242      *
 243      * @param typeName the type name
 244      */
 245     private JSType(final String typeName) {
 246         this.typeName = typeName;
 247     }
 248 
 249     /**
 250      * The external type name as returned by ECMAScript "typeof" operator
 251      *
 252      * @return type name for this type
 253      */


 379     public static boolean isStrictlyRepresentableAsInt(final double number) {
 380         return isRepresentableAsInt(number) && isNotNegativeZero(number);
 381     }
 382 
 383     /**
 384      * Returns true if Object can be represented as an int
 385      *
 386      * @param obj an object to inspect
 387      *
 388      * @return true for int representable objects
 389      */
 390     public static boolean isRepresentableAsInt(final Object obj) {
 391         if (obj instanceof Number) {
 392             return isRepresentableAsInt(((Number)obj).doubleValue());
 393         }
 394         return false;
 395     }
 396 
 397     /**
 398      * Returns true if double number can be represented as a long. Note that it returns true for negative
 399      * zero.
 400      *
 401      * @param number a double to inspect
 402      * @return true for long representable doubles
 403      */
 404     public static boolean isRepresentableAsLong(final double number) {
 405         return (long)number == number;
 406     }
 407 
 408     /**
 409      * Returns true if long number can be represented as double without loss of precision.
 410      * @param number a long number
 411      * @return true if the double representation does not lose precision














 412      */
 413     public static boolean isRepresentableAsDouble(final long number) {
 414         return MAX_PRECISE_DOUBLE >= number && number >= MIN_PRECISE_DOUBLE;



 415     }
 416 
 417     /**
 418      * Returns true if the number is not the negative zero ({@code -0.0d}).
 419      * @param number the number to test
 420      * @return true if it is not the negative zero, false otherwise.
 421      */
 422     private static boolean isNotNegativeZero(final double number) {
 423         return Double.doubleToRawLongBits(number) != 0x8000000000000000L;
 424     }
 425 
 426     /**
 427      * Check whether an object is primitive
 428      *
 429      * @param obj an object
 430      *
 431      * @return true if object is primitive (includes null and undefined)
 432      */
 433     public static boolean isPrimitive(final Object obj) {
 434         return obj == null ||


 584      */
 585     public static Object toPropertyKey(final Object obj) {
 586         return obj instanceof Symbol ? obj : toStringImpl(obj, false);
 587     }
 588 
 589     /**
 590      * If obj is an instance of {@link ConsString} cast to CharSequence, else return
 591      * result of {@link #toString(Object)}.
 592      *
 593      * @param obj an object
 594      * @return an instance of String or ConsString
 595      */
 596     public static CharSequence toCharSequence(final Object obj) {
 597         if (obj instanceof ConsString) {
 598             return (CharSequence) obj;
 599         }
 600         return toString(obj);
 601     }
 602 
 603     /**
















 604      * Returns true if object represents a primitive JavaScript string value.
 605      * @param obj the object
 606      * @return true if the object represents a primitive JavaScript string value.
 607      */
 608     public static boolean isString(final Object obj) {
 609         return obj instanceof String || obj instanceof ConsString;
 610     }
 611 
 612     /**
 613      * JavaScript compliant conversion of integer to String
 614      *
 615      * @param num an integer
 616      *
 617      * @return a string
 618      */
 619     public static String toString(final int num) {
 620         return Integer.toString(num);
 621     }
 622 
 623     /**


 951      * caller's responsibility to handle such values correctly.</p>
 952      *
 953      * @param obj  an object
 954      * @return a long
 955      */
 956     public static long toLong(final Object obj) {
 957         return obj instanceof Long ? ((Long)obj) : toLong(toNumber(obj));
 958     }
 959 
 960     /**
 961      * Converts a double to long.
 962      *
 963      * @param num the double to convert
 964      * @return the converted long value
 965      */
 966     public static long toLong(final double num) {
 967         return (long)num;
 968     }
 969 
 970     /**





























 971      * JavaScript compliant Object to int32 conversion
 972      * See ECMA 9.5 ToInt32
 973      *
 974      * @param obj an object
 975      * @return an int32
 976      */
 977     public static int toInt32(final Object obj) {
 978         return toInt32(toNumber(obj));
 979     }
 980 
 981     /**
 982      * Optimistic int conversion - throws UnwarrantedOptimismException if double, long or Object
 983      *
 984      * @param obj           object to convert
 985      * @param programPoint  program point
 986      * @return double
 987      */
 988     public static int toInt32Optimistic(final Object obj, final int programPoint) {
 989         if (obj != null && obj.getClass() == Integer.class) {
 990             return ((Integer)obj);
 991         }
 992         throw new UnwarrantedOptimismException(obj, programPoint);
 993     }
 994 
 995     /**
 996      * Object to int conversion that delegates to either {@link #toInt32(Object)} or to
 997      * {@link #toInt32Optimistic(Object, int)} depending on whether the program point is valid or not.
 998      * @param obj the object to convert
 999      * @param programPoint the program point; can be invalid.
1000      * @return the value converted to int
1001      * @throws UnwarrantedOptimismException if the value can't be represented as int and the program point is valid.
1002      */
1003     public static int toInt32MaybeOptimistic(final Object obj, final int programPoint) {
1004         return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj);
1005     }
1006 




1007     /**
1008      * JavaScript compliant long to int32 conversion
1009      *
1010      * @param num a long
1011      * @return an int32
1012      */
1013     public static int toInt32(final long num) {
1014         return (int)(num >= MIN_PRECISE_DOUBLE && num <= MAX_PRECISE_DOUBLE ? num : (long)(num % INT32_LIMIT));
1015     }
1016 
1017 
1018     /**
1019      * JavaScript compliant number to int32 conversion
1020      *
1021      * @param num a number
1022      * @return an int32
1023      */
1024     public static int toInt32(final double num) {
1025         return (int)doubleToInt32(num);
1026     }


1039      * JavaScript compliant number to uint32 conversion
1040      *
1041      * @param num a number
1042      * @return a uint32
1043      */
1044     public static long toUint32(final double num) {
1045         return doubleToInt32(num) & MAX_UINT;
1046     }
1047 
1048     /**
1049      * JavaScript compliant int to uint32 conversion
1050      *
1051      * @param num an int
1052      * @return a uint32
1053      */
1054     public static long toUint32(final int num) {
1055         return num & MAX_UINT;
1056     }
1057 
1058     /**
1059      * Optimistic JavaScript compliant int to uint32 conversion
1060      * @param num an int
1061      * @param pp the program point
1062      * @return the uint32 value if it can be represented by an int
1063      * @throws UnwarrantedOptimismException if uint32 value cannot be represented by an int
1064      */
1065     public static int toUint32Optimistic(final int num, final int pp) {
1066         if (num >= 0) {
1067             return num;
1068         }
1069         throw new UnwarrantedOptimismException(toUint32Double(num), pp, Type.NUMBER);
1070     }
1071 
1072     /**
1073      * JavaScript compliant int to uint32 conversion with double return type
1074      * @param num an int
1075      * @return the uint32 value as double
1076      */
1077     public static double toUint32Double(final int num) {
1078         return (double) toUint32(num);
1079     }
1080 
1081     /**
1082      * JavaScript compliant Object to uint16 conversion
1083      * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
1084      *
1085      * @param obj an object
1086      * @return a uint16
1087      */
1088     public static int toUint16(final Object obj) {
1089         return toUint16(toNumber(obj));
1090     }
1091 
1092     /**
1093      * JavaScript compliant number to uint16 conversion
1094      *
1095      * @param num a number
1096      * @return a uint16
1097      */
1098     public static int toUint16(final int num) {
1099         return num & 0xffff;
1100     }
1101 


1392     private static Object throwUnwarrantedOptimismException(final Object value, final int programPoint) {
1393         throw new UnwarrantedOptimismException(value, programPoint);
1394     }
1395 
1396     /**
1397      * Wrapper for addExact
1398      *
1399      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1400      * containing the result and the program point of the failure
1401      *
1402      * @param x first term
1403      * @param y second term
1404      * @param programPoint program point id
1405      * @return the result
1406      * @throws UnwarrantedOptimismException if overflow occurs
1407      */
1408     public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1409         try {
1410             return Math.addExact(x, y);
1411         } catch (final ArithmeticException e) {




















1412             throw new UnwarrantedOptimismException((double)x + (double)y, programPoint);
1413         }
1414     }
1415 
1416     /**
1417      * Wrapper for subExact
1418      *
1419      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1420      * containing the result and the program point of the failure
1421      *
1422      * @param x first term
1423      * @param y second term
1424      * @param programPoint program point id
1425      * @return the result
1426      * @throws UnwarrantedOptimismException if overflow occurs
1427      */
1428     public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1429         try {
1430             return Math.subtractExact(x, y);
1431         } catch (final ArithmeticException e) {




















1432             throw new UnwarrantedOptimismException((double)x - (double)y, programPoint);
1433         }
1434     }
1435 
1436     /**
1437      * Wrapper for mulExact
1438      *
1439      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1440      * containing the result and the program point of the failure
1441      *
1442      * @param x first term
1443      * @param y second term
1444      * @param programPoint program point id
1445      * @return the result
1446      * @throws UnwarrantedOptimismException if overflow occurs
1447      */
1448     public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1449         try {
1450             return Math.multiplyExact(x, y);
1451         } catch (final ArithmeticException e) {




















1452             throw new UnwarrantedOptimismException((double)x * (double)y, programPoint);
1453         }
1454     }
1455 
1456     /**
1457      * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
1458      * int.
1459      *
1460      * @param x first term
1461      * @param y second term
1462      * @param programPoint program point id
1463      * @return the result
1464      * @throws UnwarrantedOptimismException if the result of the division can't be represented as int.
1465      */
1466     public static int divExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1467         final int res;
1468         try {
1469             res = x / y;
1470         } catch (final ArithmeticException e) {
1471             assert y == 0; // Only div by zero anticipated


1503 
1504     /**
1505      * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
1506      *
1507      * @param x first term
1508      * @param y second term
1509      * @param programPoint program point id
1510      * @return the result
1511      * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
1512      */
1513     public static int remExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1514         try {
1515             return x % y;
1516         } catch (final ArithmeticException e) {
1517             assert y == 0; // Only mod by zero anticipated
1518             throw new UnwarrantedOptimismException(Double.NaN, programPoint);
1519         }
1520     }
1521 
1522     /**

































































1523      * Wrapper for decrementExact
1524      *
1525      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1526      * containing the result and the program point of the failure
1527      *
1528      * @param x number to negate
1529      * @param programPoint program point id
1530      * @return the result
1531      * @throws UnwarrantedOptimismException if overflow occurs
1532      */
1533     public static int decrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1534         try {
1535             return Math.decrementExact(x);
1536         } catch (final ArithmeticException e) {
1537             throw new UnwarrantedOptimismException((double)x - 1, programPoint);



















1538         }
1539     }
1540 
1541     /**
1542      * Wrapper for incrementExact
1543      *
1544      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1545      * containing the result and the program point of the failure
1546      *
1547      * @param x the number to increment
1548      * @param programPoint program point id
1549      * @return the result
1550      * @throws UnwarrantedOptimismException if overflow occurs
1551      */
1552     public static int incrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1553         try {
1554             return Math.incrementExact(x);
1555         } catch (final ArithmeticException e) {
1556             throw new UnwarrantedOptimismException((double)x + 1, programPoint);



















1557         }
1558     }
1559 
1560     /**
1561      * Wrapper for negateExact
1562      *
1563      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1564      * containing the result and the program point of the failure
1565      *
1566      * @param x the number to negate
1567      * @param programPoint program point id
1568      * @return the result
1569      * @throws UnwarrantedOptimismException if overflow occurs
1570      */
1571     public static int negateExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1572         try {
1573             if (x == 0) {
1574                 throw new UnwarrantedOptimismException(-0.0, programPoint);
1575             }
1576             return Math.negateExact(x);
1577         } catch (final ArithmeticException e) {






















1578             throw new UnwarrantedOptimismException(-(double)x, programPoint);
1579         }
1580     }
1581 
1582     /**
1583      * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
1584      *
1585      * @param type the type
1586      *
1587      * @return the accessor index, or -1 if no accessor of this type exists
1588      */
1589     public static int getAccessorTypeIndex(final Type type) {
1590         return getAccessorTypeIndex(type.getTypeClass());
1591     }
1592 
1593     /**
1594      * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
1595      *
1596      * Note that this is hardcoded with respect to the dynamic contents of the accessor
1597      * types array for speed. Hotspot got stuck with this as 5% of the runtime in
1598      * a benchmark when it looped over values and increased an index counter. :-(
1599      *
1600      * @param type the type
1601      *
1602      * @return the accessor index, or -1 if no accessor of this type exists
1603      */
1604     public static int getAccessorTypeIndex(final Class<?> type) {
1605         if (type == null) {
1606             return TYPE_UNDEFINED_INDEX;
1607         } else if (type == int.class) {
1608             return TYPE_INT_INDEX;


1609         } else if (type == double.class) {
1610             return TYPE_DOUBLE_INDEX;
1611         } else if (!type.isPrimitive()) {
1612             return TYPE_OBJECT_INDEX;
1613         }
1614         return -1;
1615     }
1616 
1617     /**
1618      * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
1619      * Indexes are ordered narrower{@literal ->}wider / optimistic{@literal ->}pessimistic. Invalidations always
1620      * go to a type of higher index
1621      *
1622      * @param index accessor type index
1623      *
1624      * @return a type corresponding to the index.
1625      */
1626 
1627     public static Type getAccessorType(final int index) {
1628         return ACCESSOR_TYPES.get(index);


1693     }
1694 
1695     private static Object invoke(final MethodHandle mh, final Object arg) {
1696         try {
1697             return mh.invoke(arg);
1698         } catch (final RuntimeException | Error e) {
1699             throw e;
1700         } catch (final Throwable t) {
1701             throw new RuntimeException(t);
1702         }
1703     }
1704 
1705     /**
1706      * Returns the boxed version of a primitive class
1707      * @param clazz the class
1708      * @return the boxed type of clazz, or unchanged if not primitive
1709      */
1710     public static Class<?> getBoxedClass(final Class<?> clazz) {
1711         if (clazz == int.class) {
1712             return Integer.class;


1713         } else if (clazz == double.class) {
1714             return Double.class;
1715         }
1716         assert !clazz.isPrimitive();
1717         return clazz;
1718     }
1719 
1720     /**
1721      * Create a method handle constant of the correct primitive type
1722      * for a constant object
1723      * @param o object
1724      * @return constant function that returns object
1725      */
1726     public static MethodHandle unboxConstant(final Object o) {
1727         if (o != null) {
1728             if (o.getClass() == Integer.class) {
1729                 return MH.constant(int.class, ((Integer)o));


1730             } else if (o.getClass() == Double.class) {
1731                 return MH.constant(double.class, ((Double)o));
1732             }
1733         }
1734         return MH.constant(Object.class, o);
1735     }
1736 
1737     /**
1738      * Get the unboxed (primitive) type for an object
1739      * @param o object
1740      * @return primitive type or Object.class if not primitive
1741      */
1742     public static Class<?> unboxedFieldType(final Object o) {
1743         if (o == null) {
1744             return Object.class;
1745         } else if (o.getClass() == Integer.class) {
1746             return int.class;


1747         } else if (o.getClass() == Double.class) {
1748             return double.class;
1749         } else {
1750             return Object.class;
1751         }
1752     }
1753 
1754     private static List<MethodHandle> toUnmodifiableList(final MethodHandle... methodHandles) {
1755         return Collections.unmodifiableList(Arrays.asList(methodHandles));
1756     }
1757 }
< prev index next >