< prev index next >

src/jdk/nashorn/internal/runtime/JSType.java

Print this page




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



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


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




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


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


 611      */
 612     public static String toString(final Object obj) {
 613         return toStringImpl(obj, false);
 614     }
 615 
 616     /**
 617      * If obj is an instance of {@link ConsString} cast to CharSequence, else return
 618      * result of {@link #toString(Object)}.
 619      *
 620      * @param obj an object
 621      * @return an instance of String or ConsString
 622      */
 623     public static CharSequence toCharSequence(final Object obj) {
 624         if (obj instanceof ConsString) {
 625             return (CharSequence) obj;
 626         }
 627         return toString(obj);
 628     }
 629 
 630     /**
 631      * Check whether a string is representable as a JavaScript number
 632      *
 633      * @param str  a string
 634      *
 635      * @return     true if string can be represented as a number
 636      */
 637     public static boolean isNumber(final String str) {
 638         try {
 639             Double.parseDouble(str);
 640             return true;
 641         } catch (final NumberFormatException e) {
 642             return false;
 643         }
 644     }
 645 
 646     /**
 647      * Returns true if object represents a primitive JavaScript string value.
 648      * @param obj the object
 649      * @return true if the object represents a primitive JavaScript string value.
 650      */
 651     public static boolean isString(final Object obj) {
 652         return obj instanceof String || obj instanceof ConsString;
 653     }
 654 
 655     /**
 656      * JavaScript compliant conversion of integer to String
 657      *
 658      * @param num an integer
 659      *
 660      * @return a string
 661      */
 662     public static String toString(final int num) {
 663         return Integer.toString(num);
 664     }
 665 
 666     /**


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


1113      * JavaScript compliant number to uint32 conversion
1114      *
1115      * @param num a number
1116      * @return a uint32
1117      */
1118     public static long toUint32(final double num) {
1119         return doubleToInt32(num) & MAX_UINT;
1120     }
1121 
1122     /**
1123      * JavaScript compliant int to uint32 conversion
1124      *
1125      * @param num an int
1126      * @return a uint32
1127      */
1128     public static long toUint32(final int num) {
1129         return num & MAX_UINT;
1130     }
1131 
1132     /**























1133      * JavaScript compliant Object to uint16 conversion
1134      * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
1135      *
1136      * @param obj an object
1137      * @return a uint16
1138      */
1139     public static int toUint16(final Object obj) {
1140         return toUint16(toNumber(obj));
1141     }
1142 
1143     /**
1144      * JavaScript compliant number to uint16 conversion
1145      *
1146      * @param num a number
1147      * @return a uint16
1148      */
1149     public static int toUint16(final int num) {
1150         return num & 0xffff;
1151     }
1152 


1436     private static Object throwUnwarrantedOptimismException(final Object value, final int programPoint) {
1437         throw new UnwarrantedOptimismException(value, programPoint);
1438     }
1439 
1440     /**
1441      * Wrapper for addExact
1442      *
1443      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1444      * containing the result and the program point of the failure
1445      *
1446      * @param x first term
1447      * @param y second term
1448      * @param programPoint program point id
1449      * @return the result
1450      * @throws UnwarrantedOptimismException if overflow occurs
1451      */
1452     public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1453         try {
1454             return Math.addExact(x, y);
1455         } catch (final ArithmeticException e) {
1456             throw new UnwarrantedOptimismException((long)x + (long)y, programPoint);
1457         }
1458     }
1459 
1460     /**
1461      * Wrapper for addExact
1462      *
1463      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1464      * containing the result and the program point of the failure
1465      *
1466      * @param x first term
1467      * @param y second term
1468      * @param programPoint program point id
1469      * @return the result
1470      * @throws UnwarrantedOptimismException if overflow occurs
1471      */
1472     public static long addExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1473         try {
1474             return Math.addExact(x, y);
1475         } catch (final ArithmeticException e) {
1476             throw new UnwarrantedOptimismException((double)x + (double)y, programPoint);
1477         }
1478     }
1479 
1480     /**
1481      * Wrapper for subExact
1482      *
1483      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1484      * containing the result and the program point of the failure
1485      *
1486      * @param x first term
1487      * @param y second term
1488      * @param programPoint program point id
1489      * @return the result
1490      * @throws UnwarrantedOptimismException if overflow occurs
1491      */
1492     public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1493         try {
1494             return Math.subtractExact(x, y);
1495         } catch (final ArithmeticException e) {
1496             throw new UnwarrantedOptimismException((long)x - (long)y, programPoint);
1497         }
1498     }
1499 
1500     /**
1501      * Wrapper for subExact
1502      *
1503      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1504      * containing the result and the program point of the failure
1505      *
1506      * @param x first term
1507      * @param y second term
1508      * @param programPoint program point id
1509      * @return the result
1510      * @throws UnwarrantedOptimismException if overflow occurs
1511      */
1512     public static long subExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1513         try {
1514             return Math.subtractExact(x, y);
1515         } catch (final ArithmeticException e) {
1516             throw new UnwarrantedOptimismException((double)x - (double)y, programPoint);
1517         }
1518     }
1519 
1520     /**
1521      * Wrapper for mulExact
1522      *
1523      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1524      * containing the result and the program point of the failure
1525      *
1526      * @param x first term
1527      * @param y second term
1528      * @param programPoint program point id
1529      * @return the result
1530      * @throws UnwarrantedOptimismException if overflow occurs
1531      */
1532     public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1533         try {
1534             return Math.multiplyExact(x, y);
1535         } catch (final ArithmeticException e) {
1536             throw new UnwarrantedOptimismException((long)x * (long)y, programPoint);
1537         }
1538     }
1539 
1540     /**
1541      * Wrapper for mulExact
1542      *
1543      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1544      * containing the result and the program point of the failure
1545      *
1546      * @param x first term
1547      * @param y second term
1548      * @param programPoint program point id
1549      * @return the result
1550      * @throws UnwarrantedOptimismException if overflow occurs
1551      */
1552     public static long mulExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
1553         try {
1554             return Math.multiplyExact(x, y);
1555         } catch (final ArithmeticException e) {
1556             throw new UnwarrantedOptimismException((double)x * (double)y, programPoint);
1557         }
1558     }
1559 
1560     /**
1561      * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
1562      * int.
1563      *
1564      * @param x first term
1565      * @param y second term
1566      * @param programPoint program point id
1567      * @return the result
1568      * @throws UnwarrantedOptimismException if the result of the division can't be represented as int.
1569      */
1570     public static int divExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1571         final int res;
1572         try {
1573             res = x / y;
1574         } catch (final ArithmeticException e) {
1575             assert y == 0; // Only div by zero anticipated


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


1920     }
1921 
1922     private static Object invoke(final MethodHandle mh, final Object arg) {
1923         try {
1924             return mh.invoke(arg);
1925         } catch (final RuntimeException | Error e) {
1926             throw e;
1927         } catch (final Throwable t) {
1928             throw new RuntimeException(t);
1929         }
1930     }
1931 
1932     /**
1933      * Returns the boxed version of a primitive class
1934      * @param clazz the class
1935      * @return the boxed type of clazz, or unchanged if not primitive
1936      */
1937     public static Class<?> getBoxedClass(final Class<?> clazz) {
1938         if (clazz == int.class) {
1939             return Integer.class;
1940         } else if (clazz == long.class) {
1941             return Long.class;
1942         } else if (clazz == double.class) {
1943             return Double.class;
1944         }
1945         assert !clazz.isPrimitive();
1946         return clazz;
1947     }
1948 
1949     /**
1950      * Create a method handle constant of the correct primitive type
1951      * for a constant object
1952      * @param o object
1953      * @return constant function that returns object
1954      */
1955     public static MethodHandle unboxConstant(final Object o) {
1956         if (o != null) {
1957             if (o.getClass() == Integer.class) {
1958                 return MH.constant(int.class, ((Integer)o).intValue());
1959             } else if (o.getClass() == Long.class) {
1960                 return MH.constant(long.class, ((Long)o).longValue());
1961             } else if (o.getClass() == Double.class) {
1962                 return MH.constant(double.class, ((Double)o).doubleValue());
1963             }
1964         }
1965         return MH.constant(Object.class, o);
1966     }
1967 
1968     /**
1969      * Get the unboxed (primitive) type for an object
1970      * @param o object
1971      * @return primitive type or Object.class if not primitive
1972      */
1973     public static Class<?> unboxedFieldType(final Object o) {
1974         if (o == null) {
1975             return Object.class;
1976         } else if (o.getClass() == Integer.class) {
1977             return int.class;
1978         } else if (o.getClass() == Long.class) {
1979             return long.class;
1980         } else if (o.getClass() == Double.class) {
1981             return double.class;
1982         } else {
1983             return Object.class;
1984         }
1985     }
1986 
1987     private static final List<MethodHandle> toUnmodifiableList(final MethodHandle... methodHandles) {
1988         return Collections.unmodifiableList(Arrays.asList(methodHandles));
1989     }
1990 }


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



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


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






























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

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


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

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

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

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


 367     public static boolean isStrictlyRepresentableAsInt(final double number) {
 368         return isRepresentableAsInt(number) && isNotNegativeZero(number);
 369     }
 370 
 371     /**
 372      * Returns true if Object can be represented as an int
 373      *
 374      * @param obj an object to inspect
 375      *
 376      * @return true for int representable objects
 377      */
 378     public static boolean isRepresentableAsInt(final Object obj) {
 379         if (obj instanceof Number) {
 380             return isRepresentableAsInt(((Number)obj).doubleValue());
 381         }
 382         return false;
 383     }
 384 
 385     /**
 386      * Returns true if double number can be represented as a long. Note that it returns true for negative
 387      * zero.
 388      *
 389      * @param number a double to inspect
 390      * @return true for long representable doubles
 391      */
 392     public static boolean isRepresentableAsLong(final double number) {
 393         return (long)number == number;
 394     }
 395 
 396     /**
 397      * Returns true if long number can be represented as double without loss of precision.
 398      * @param number a long number
 399      * @return true if the double representation does not lose precision














 400      */
 401     public static boolean isRepresentableAsDouble(final long number) {
 402         return MAX_PRECISE_DOUBLE >= number && number >= MIN_PRECISE_DOUBLE;



 403     }
 404 
 405     /**
 406      * Returns true if the number is not the negative zero ({@code -0.0d}).
 407      * @param number the number to test
 408      * @return true if it is not the negative zero, false otherwise.
 409      */
 410     private static boolean isNotNegativeZero(final double number) {
 411         return Double.doubleToRawLongBits(number) != 0x8000000000000000L;
 412     }
 413 
 414     /**
 415      * Check whether an object is primitive
 416      *
 417      * @param obj an object
 418      *
 419      * @return true if object is primitive (includes null and undefined)
 420      */
 421     public static boolean isPrimitive(final Object obj) {
 422         return obj == null ||


 562      */
 563     public static String toString(final Object obj) {
 564         return toStringImpl(obj, false);
 565     }
 566 
 567     /**
 568      * If obj is an instance of {@link ConsString} cast to CharSequence, else return
 569      * result of {@link #toString(Object)}.
 570      *
 571      * @param obj an object
 572      * @return an instance of String or ConsString
 573      */
 574     public static CharSequence toCharSequence(final Object obj) {
 575         if (obj instanceof ConsString) {
 576             return (CharSequence) obj;
 577         }
 578         return toString(obj);
 579     }
 580 
 581     /**
















 582      * Returns true if object represents a primitive JavaScript string value.
 583      * @param obj the object
 584      * @return true if the object represents a primitive JavaScript string value.
 585      */
 586     public static boolean isString(final Object obj) {
 587         return obj instanceof String || obj instanceof ConsString;
 588     }
 589 
 590     /**
 591      * JavaScript compliant conversion of integer to String
 592      *
 593      * @param num an integer
 594      *
 595      * @return a string
 596      */
 597     public static String toString(final int num) {
 598         return Integer.toString(num);
 599     }
 600 
 601     /**


 927      * caller's responsibility to handle such values correctly.</p>
 928      *
 929      * @param obj  an object
 930      * @return a long
 931      */
 932     public static long toLong(final Object obj) {
 933         return obj instanceof Long ? ((Long)obj).longValue() : toLong(toNumber(obj));
 934     }
 935 
 936     /**
 937      * Converts a double to long.
 938      *
 939      * @param num the double to convert
 940      * @return the converted long value
 941      */
 942     public static long toLong(final double num) {
 943         return (long)num;
 944     }
 945 
 946     /**





























 947      * JavaScript compliant Object to int32 conversion
 948      * See ECMA 9.5 ToInt32
 949      *
 950      * @param obj an object
 951      * @return an int32
 952      */
 953     public static int toInt32(final Object obj) {
 954         return toInt32(toNumber(obj));
 955     }
 956 
 957     /**
 958      * Optimistic int conversion - throws UnwarrantedOptimismException if double, long or Object
 959      *
 960      * @param obj           object to convert
 961      * @param programPoint  program point
 962      * @return double
 963      */
 964     public static int toInt32Optimistic(final Object obj, final int programPoint) {
 965         if (obj != null && obj.getClass() == Integer.class) {
 966             return ((Integer)obj).intValue();
 967         }
 968         throw new UnwarrantedOptimismException(obj, programPoint);
 969     }
 970 
 971     /**
 972      * Object to int conversion that delegates to either {@link #toInt32(Object)} or to
 973      * {@link #toInt32Optimistic(Object, int)} depending on whether the program point is valid or not.
 974      * @param obj the object to convert
 975      * @param programPoint the program point; can be invalid.
 976      * @return the value converted to int
 977      * @throws UnwarrantedOptimismException if the value can't be represented as int and the program point is valid.
 978      */
 979     public static int toInt32MaybeOptimistic(final Object obj, final int programPoint) {
 980         return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj);
 981     }
 982 




 983     /**
 984      * JavaScript compliant long to int32 conversion
 985      *
 986      * @param num a long
 987      * @return an int32
 988      */
 989     public static int toInt32(final long num) {
 990         return (int)(num >= MIN_PRECISE_DOUBLE && num <= MAX_PRECISE_DOUBLE ? num : (long)(num % INT32_LIMIT));
 991     }
 992 
 993 
 994     /**
 995      * JavaScript compliant number to int32 conversion
 996      *
 997      * @param num a number
 998      * @return an int32
 999      */
1000     public static int toInt32(final double num) {
1001         return (int)doubleToInt32(num);
1002     }


1015      * JavaScript compliant number to uint32 conversion
1016      *
1017      * @param num a number
1018      * @return a uint32
1019      */
1020     public static long toUint32(final double num) {
1021         return doubleToInt32(num) & MAX_UINT;
1022     }
1023 
1024     /**
1025      * JavaScript compliant int to uint32 conversion
1026      *
1027      * @param num an int
1028      * @return a uint32
1029      */
1030     public static long toUint32(final int num) {
1031         return num & MAX_UINT;
1032     }
1033 
1034     /**
1035      * Optimistic JavaScript compliant int to uint32 conversion
1036      * @param num an int
1037      * @param pp the program point
1038      * @return the uint32 value if it can be represented by an int
1039      * @throws UnwarrantedOptimismException if uint32 value cannot be represented by an int
1040      */
1041     public static int toUint32Optimistic(final int num, final int pp) {
1042         if (num >= 0) {
1043             return num;
1044         }
1045         throw new UnwarrantedOptimismException(toUint32Double(num), pp, Type.NUMBER);
1046     }
1047 
1048     /**
1049      * JavaScript compliant int to uint32 conversion with double return type
1050      * @param num an int
1051      * @return the uint32 value as double
1052      */
1053     public static double toUint32Double(final int num) {
1054         return (double) toUint32(num);
1055     }
1056 
1057     /**
1058      * JavaScript compliant Object to uint16 conversion
1059      * ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
1060      *
1061      * @param obj an object
1062      * @return a uint16
1063      */
1064     public static int toUint16(final Object obj) {
1065         return toUint16(toNumber(obj));
1066     }
1067 
1068     /**
1069      * JavaScript compliant number to uint16 conversion
1070      *
1071      * @param num a number
1072      * @return a uint16
1073      */
1074     public static int toUint16(final int num) {
1075         return num & 0xffff;
1076     }
1077 


1361     private static Object throwUnwarrantedOptimismException(final Object value, final int programPoint) {
1362         throw new UnwarrantedOptimismException(value, programPoint);
1363     }
1364 
1365     /**
1366      * Wrapper for addExact
1367      *
1368      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1369      * containing the result and the program point of the failure
1370      *
1371      * @param x first term
1372      * @param y second term
1373      * @param programPoint program point id
1374      * @return the result
1375      * @throws UnwarrantedOptimismException if overflow occurs
1376      */
1377     public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1378         try {
1379             return Math.addExact(x, y);
1380         } catch (final ArithmeticException e) {




















1381             throw new UnwarrantedOptimismException((double)x + (double)y, programPoint);
1382         }
1383     }
1384 
1385     /**
1386      * Wrapper for subExact
1387      *
1388      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1389      * containing the result and the program point of the failure
1390      *
1391      * @param x first term
1392      * @param y second term
1393      * @param programPoint program point id
1394      * @return the result
1395      * @throws UnwarrantedOptimismException if overflow occurs
1396      */
1397     public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1398         try {
1399             return Math.subtractExact(x, y);
1400         } catch (final ArithmeticException e) {




















1401             throw new UnwarrantedOptimismException((double)x - (double)y, programPoint);
1402         }
1403     }
1404 
1405     /**
1406      * Wrapper for mulExact
1407      *
1408      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1409      * containing the result and the program point of the failure
1410      *
1411      * @param x first term
1412      * @param y second term
1413      * @param programPoint program point id
1414      * @return the result
1415      * @throws UnwarrantedOptimismException if overflow occurs
1416      */
1417     public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1418         try {
1419             return Math.multiplyExact(x, y);
1420         } catch (final ArithmeticException e) {




















1421             throw new UnwarrantedOptimismException((double)x * (double)y, programPoint);
1422         }
1423     }
1424 
1425     /**
1426      * Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
1427      * int.
1428      *
1429      * @param x first term
1430      * @param y second term
1431      * @param programPoint program point id
1432      * @return the result
1433      * @throws UnwarrantedOptimismException if the result of the division can't be represented as int.
1434      */
1435     public static int divExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1436         final int res;
1437         try {
1438             res = x / y;
1439         } catch (final ArithmeticException e) {
1440             assert y == 0; // Only div by zero anticipated


1472 
1473     /**
1474      * Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
1475      *
1476      * @param x first term
1477      * @param y second term
1478      * @param programPoint program point id
1479      * @return the result
1480      * @throws UnwarrantedOptimismException if the modulo can't be represented as int.
1481      */
1482     public static int remExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
1483         try {
1484             return x % y;
1485         } catch (final ArithmeticException e) {
1486             assert y == 0; // Only mod by zero anticipated
1487             throw new UnwarrantedOptimismException(Double.NaN, programPoint);
1488         }
1489     }
1490 
1491     /**

































































1492      * Wrapper for decrementExact
1493      *
1494      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1495      * containing the result and the program point of the failure
1496      *
1497      * @param x number to negate
1498      * @param programPoint program point id
1499      * @return the result
1500      * @throws UnwarrantedOptimismException if overflow occurs
1501      */
1502     public static int decrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1503         try {
1504             return Math.decrementExact(x);
1505         } catch (final ArithmeticException e) {
1506             throw new UnwarrantedOptimismException((double)x - 1, programPoint);



















1507         }
1508     }
1509 
1510     /**
1511      * Wrapper for incrementExact
1512      *
1513      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1514      * containing the result and the program point of the failure
1515      *
1516      * @param x the number to increment
1517      * @param programPoint program point id
1518      * @return the result
1519      * @throws UnwarrantedOptimismException if overflow occurs
1520      */
1521     public static int incrementExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1522         try {
1523             return Math.incrementExact(x);
1524         } catch (final ArithmeticException e) {
1525             throw new UnwarrantedOptimismException((double)x + 1, programPoint);



















1526         }
1527     }
1528 
1529     /**
1530      * Wrapper for negateExact
1531      *
1532      * Catches ArithmeticException and rethrows as UnwarrantedOptimismException
1533      * containing the result and the program point of the failure
1534      *
1535      * @param x the number to negate
1536      * @param programPoint program point id
1537      * @return the result
1538      * @throws UnwarrantedOptimismException if overflow occurs
1539      */
1540     public static int negateExact(final int x, final int programPoint) throws UnwarrantedOptimismException {
1541         try {
1542             if (x == 0) {
1543                 throw new UnwarrantedOptimismException(-0.0, programPoint);
1544             }
1545             return Math.negateExact(x);
1546         } catch (final ArithmeticException e) {






















1547             throw new UnwarrantedOptimismException(-(double)x, programPoint);
1548         }
1549     }
1550 
1551     /**
1552      * Given a type of an accessor, return its index in [0..getNumberOfAccessorTypes())
1553      *
1554      * @param type the type
1555      *
1556      * @return the accessor index, or -1 if no accessor of this type exists
1557      */
1558     public static int getAccessorTypeIndex(final Type type) {
1559         return getAccessorTypeIndex(type.getTypeClass());
1560     }
1561 
1562     /**
1563      * Given a class of an accessor, return its index in [0..getNumberOfAccessorTypes())
1564      *
1565      * Note that this is hardcoded with respect to the dynamic contents of the accessor
1566      * types array for speed. Hotspot got stuck with this as 5% of the runtime in
1567      * a benchmark when it looped over values and increased an index counter. :-(
1568      *
1569      * @param type the type
1570      *
1571      * @return the accessor index, or -1 if no accessor of this type exists
1572      */
1573     public static int getAccessorTypeIndex(final Class<?> type) {
1574         if (type == null) {
1575             return TYPE_UNDEFINED_INDEX;
1576         } else if (type == int.class) {
1577             return TYPE_INT_INDEX;


1578         } else if (type == double.class) {
1579             return TYPE_DOUBLE_INDEX;
1580         } else if (!type.isPrimitive()) {
1581             return TYPE_OBJECT_INDEX;
1582         }
1583         return -1;
1584     }
1585 
1586     /**
1587      * Return the accessor type based on its index in [0..getNumberOfAccessorTypes())
1588      * Indexes are ordered narrower{@literal ->}wider / optimistic{@literal ->}pessimistic. Invalidations always
1589      * go to a type of higher index
1590      *
1591      * @param index accessor type index
1592      *
1593      * @return a type corresponding to the index.
1594      */
1595 
1596     public static Type getAccessorType(final int index) {
1597         return ACCESSOR_TYPES.get(index);


1658     }
1659 
1660     private static Object invoke(final MethodHandle mh, final Object arg) {
1661         try {
1662             return mh.invoke(arg);
1663         } catch (final RuntimeException | Error e) {
1664             throw e;
1665         } catch (final Throwable t) {
1666             throw new RuntimeException(t);
1667         }
1668     }
1669 
1670     /**
1671      * Returns the boxed version of a primitive class
1672      * @param clazz the class
1673      * @return the boxed type of clazz, or unchanged if not primitive
1674      */
1675     public static Class<?> getBoxedClass(final Class<?> clazz) {
1676         if (clazz == int.class) {
1677             return Integer.class;


1678         } else if (clazz == double.class) {
1679             return Double.class;
1680         }
1681         assert !clazz.isPrimitive();
1682         return clazz;
1683     }
1684 
1685     /**
1686      * Create a method handle constant of the correct primitive type
1687      * for a constant object
1688      * @param o object
1689      * @return constant function that returns object
1690      */
1691     public static MethodHandle unboxConstant(final Object o) {
1692         if (o != null) {
1693             if (o.getClass() == Integer.class) {
1694                 return MH.constant(int.class, ((Integer)o).intValue());


1695             } else if (o.getClass() == Double.class) {
1696                 return MH.constant(double.class, ((Double)o).doubleValue());
1697             }
1698         }
1699         return MH.constant(Object.class, o);
1700     }
1701 
1702     /**
1703      * Get the unboxed (primitive) type for an object
1704      * @param o object
1705      * @return primitive type or Object.class if not primitive
1706      */
1707     public static Class<?> unboxedFieldType(final Object o) {
1708         if (o == null) {
1709             return Object.class;
1710         } else if (o.getClass() == Integer.class) {
1711             return int.class;


1712         } else if (o.getClass() == Double.class) {
1713             return double.class;
1714         } else {
1715             return Object.class;
1716         }
1717     }
1718 
1719     private static final List<MethodHandle> toUnmodifiableList(final MethodHandle... methodHandles) {
1720         return Collections.unmodifiableList(Arrays.asList(methodHandles));
1721     }
1722 }
< prev index next >