aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/runtime/JSType.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/runtime/JSType.java')
-rw-r--r--src/jdk/nashorn/internal/runtime/JSType.java28
1 files changed, 18 insertions, 10 deletions
diff --git a/src/jdk/nashorn/internal/runtime/JSType.java b/src/jdk/nashorn/internal/runtime/JSType.java
index 21977816..e972a99e 100644
--- a/src/jdk/nashorn/internal/runtime/JSType.java
+++ b/src/jdk/nashorn/internal/runtime/JSType.java
@@ -102,6 +102,8 @@ public enum JSType {
/** JavaScript compliant conversion function from Object to primitive */
public static final Call TO_PRIMITIVE = staticCall(JSType.class, "toPrimitive", Object.class, Object.class);
+ private static final double INT32_LIMIT = 4294967296.0;
+
/**
* The external type name as returned by ECMAScript "typeof" operator
*
@@ -612,10 +614,7 @@ public enum JSType {
* @return an int32
*/
public static int toInt32(final double num) {
- if (Double.isInfinite(num)) {
- return 0;
- }
- return (int)(long)num;
+ return (int)doubleToInt32(num);
}
/**
@@ -658,10 +657,7 @@ public enum JSType {
* @return a uint32
*/
public static long toUint32(final double num) {
- if (Double.isInfinite(num)) {
- return 0L;
- }
- return ((long)num) & 0xffff_ffffL;
+ return doubleToInt32(num) & MAX_UINT;
}
/**
@@ -702,10 +698,22 @@ public enum JSType {
* @return a uint16
*/
public static int toUint16(final double num) {
- if (Double.isInfinite(num)) {
+ return ((int)doubleToInt32(num)) & 0xffff;
+ }
+
+ private static long doubleToInt32(final double num) {
+ final int exponent = Math.getExponent(num);
+ if (exponent < 31) {
+ return (long) num; // Fits into 32 bits
+ }
+ if (exponent >= 84) {
+ // Either infinite or NaN or so large that shift / modulo will produce 0
+ // (52 bit mantissa + 32 bit target width).
return 0;
}
- return ((int)(long)num) & 0xffff;
+ // This is rather slow and could probably be sped up using bit-fiddling.
+ final double d = (num >= 0) ? Math.floor(num) : Math.ceil(num);
+ return (long)(d % INT32_LIMIT);
}
/**