diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-06-17 12:14:25 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-06-17 12:14:25 -0400 |
commit | 4003a1c71cfde9521fc84e5446bbdb146a6ca793 (patch) | |
tree | 5b629f12d9747bb5170d1c439170637ecad1e377 | |
parent | e526bb845d76dd920df335dedd796b8f44ab4b4e (diff) |
tighten up narrowing conversion checks
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 22 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 23 |
2 files changed, 31 insertions, 14 deletions
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 9f8c7b5f..fff8e62f 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -769,21 +769,21 @@ static public abstract class HostExpr implements Expr, MaybePrimitiveExpr{ } else { - Method m = intValueMethod; + Method m = null; gen.checkCast(NUMBER_TYPE); if(paramType == int.class) - m = intValueMethod; + m = Method.getMethod("int intCast(Object)"); else if(paramType == float.class) - m = floatValueMethod; + m = Method.getMethod("float floatCast(Object)"); else if(paramType == double.class) - m = doubleValueMethod; - else if(paramType == long.class) - m = longValueMethod; - else if(paramType == byte.class) - m = byteValueMethod; - else if(paramType == short.class) - m = shortValueMethod; - gen.invokeVirtual(NUMBER_TYPE, m); + m = Method.getMethod("double doubleCast(Object)"); + else if(paramType == long.class) + m = Method.getMethod("long longCast(Object)"); + else if(paramType == byte.class) + m = Method.getMethod("byte byteCast(Object)"); + else if(paramType == short.class) + m = Method.getMethod("short shortCast(Object)"); + gen.invokeStatic(RT_TYPE, m); } } else diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 18a770b8..0ba8a9e2 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -900,7 +900,9 @@ static public boolean booleanCast(boolean x){ } static public byte byteCast(Object x){ - long n = ((Number) x).longValue(); + if(x instanceof Byte) + return ((Byte) x).byteValue(); + long n = longCast(x); if(n < Byte.MIN_VALUE || n > Byte.MAX_VALUE) throw new IllegalArgumentException("Value out of range for byte: " + x); @@ -908,7 +910,9 @@ static public byte byteCast(Object x){ } static public short shortCast(Object x){ - long n = ((Number) x).longValue(); + if(x instanceof Short) + return ((Short) x).shortValue(); + long n = longCast(x); if(n < Short.MIN_VALUE || n > Short.MAX_VALUE) throw new IllegalArgumentException("Value out of range for short: " + x); @@ -919,7 +923,10 @@ static public int intCast(Object x){ if(x instanceof Integer) return ((Integer)x).intValue(); if(x instanceof Number) - return intCast(((Number) x).longValue()); + { + long n = longCast(x); + return intCast(n); + } return ((Character) x).charValue(); } @@ -958,6 +965,16 @@ static public int intCast(double x){ } static public long longCast(Object x){ + if(x instanceof Integer || x instanceof Long) + return ((Number) x).longValue(); + else if (x instanceof BigInteger) + { + BigInteger bi = (BigInteger) x; + if(bi.bitLength() < 64) + return bi.longValue(); + else + throw new IllegalArgumentException("Value out of range for long: " + x); + } return ((Number) x).longValue(); } |