[armedbear-cvs] r11722 - trunk/abcl/src/org/armedbear/lisp

Erik Huelsmann ehuelsmann at common-lisp.net
Wed Apr 1 19:58:14 UTC 2009


Author: ehuelsmann
Date: Wed Apr  1 15:58:11 2009
New Revision: 11722

Log:
Make sure to create Fixnums when the LispInteger/Bignum created is in the Fixnum range.

Note: After this commit, your .abcl files need to be recompiled as it makes the
  Bignum and Fixnum constructors 'private'.

Modified:
   trunk/abcl/src/org/armedbear/lisp/Bignum.java
   trunk/abcl/src/org/armedbear/lisp/Fixnum.java
   trunk/abcl/src/org/armedbear/lisp/FloatFunctions.java
   trunk/abcl/src/org/armedbear/lisp/JavaObject.java
   trunk/abcl/src/org/armedbear/lisp/Lisp.java
   trunk/abcl/src/org/armedbear/lisp/LispInteger.java
   trunk/abcl/src/org/armedbear/lisp/RuntimeClass.java
   trunk/abcl/src/org/armedbear/lisp/Stream.java
   trunk/abcl/src/org/armedbear/lisp/compiler-pass2.lisp

Modified: trunk/abcl/src/org/armedbear/lisp/Bignum.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Bignum.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Bignum.java	Wed Apr  1 15:58:11 2009
@@ -39,23 +39,40 @@
 {
   public final BigInteger value;
 
-  public static Bignum getInstance(long l) {
-    return new Bignum(l);
+  private static BigInteger MOST_NEGATIVE_FIXNUM =
+          BigInteger.valueOf(Integer.MIN_VALUE);
+  private static BigInteger MOST_POSITIVE_FIXNUM =
+          BigInteger.valueOf(Integer.MAX_VALUE);
+
+  public static LispInteger getInstance(long l) {
+      if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE)
+          return Fixnum.getInstance(l);
+      else
+          return new Bignum(l);
   }
 
-  public Bignum(long l)
-  {
-    value = BigInteger.valueOf(l);
+  public static LispInteger getInstance(BigInteger n) {
+      if (MOST_NEGATIVE_FIXNUM.compareTo(n) < 0 ||
+              MOST_POSITIVE_FIXNUM.compareTo(n) > 0)
+          return new Bignum(n);
+      else
+          return Fixnum.getInstance(n.intValue());
   }
 
-  public Bignum(BigInteger n)
+  public static LispInteger getInstance(String s, int radix) {
+      BigInteger value = new BigInteger(s, radix);
+
+      return Bignum.getInstance(value);
+  }
+
+  private Bignum(long l)
   {
-    value = n;
+    value = BigInteger.valueOf(l);
   }
 
-  public Bignum(String s, int radix)
+  private Bignum(BigInteger n)
   {
-    value = new BigInteger(s, radix);
+    value = n;
   }
 
   @Override

Modified: trunk/abcl/src/org/armedbear/lisp/Fixnum.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Fixnum.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Fixnum.java	Wed Apr  1 15:58:11 2009
@@ -252,9 +252,7 @@
   {
     if (value >= 0)
       return this;
-    if (value > Integer.MIN_VALUE)
-      return Fixnum.getInstance(-value);
-    return new Bignum(-((long)Integer.MIN_VALUE));
+    return LispInteger.getInstance(-(long)value);
   }
 
   @Override
@@ -371,37 +369,25 @@
   @Override
   public final LispObject incr()
   {
-    if (value < Integer.MAX_VALUE)
-      return Fixnum.getInstance(value + 1);
-    return new Bignum((long) value + 1);
+    return LispInteger.getInstance(1 + (long)value);
   }
 
   @Override
   public final LispObject decr()
   {
-    if (value > Integer.MIN_VALUE)
-      return Fixnum.getInstance(value - 1);
-    return new Bignum((long) value - 1);
+    return LispInteger.getInstance(-1 + (long)value);
   }
 
   @Override
   public LispObject negate()
   {
-    long result = 0L - value;
-    if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE)
-      return Fixnum.getInstance((int)result);
-    else
-      return new Bignum(result);
+    return LispInteger.getInstance((-(long)value));
   }
 
   @Override
   public LispObject add(int n)
   {
-    long result = (long) value + n;
-    if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE)
-      return Fixnum.getInstance((int)result);
-    else
-      return new Bignum(result);
+    return LispInteger.getInstance((long) value + n);
   }
 
   @Override
@@ -410,10 +396,7 @@
     if (obj instanceof Fixnum)
       {
         long result = (long) value + ((Fixnum)obj).value;
-        if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE)
-          return Fixnum.getInstance((int)result);
-        else
-          return new Bignum(result);
+        return LispInteger.getInstance(result);
       }
     if (obj instanceof Bignum)
       return number(getBigInteger().add(((Bignum)obj).value));
@@ -439,11 +422,7 @@
   @Override
   public LispObject subtract(int n)
   {
-    long result = (long) value - n;
-    if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE)
-      return Fixnum.getInstance((int)result);
-    else
-      return new Bignum(result);
+    return LispInteger.getInstance((long)value - n);
   }
 
   @Override
@@ -478,10 +457,7 @@
   public LispObject multiplyBy(int n)
   {
     long result = (long) value * n;
-    if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE)
-      return Fixnum.getInstance((int)result);
-    else
-      return new Bignum(result);
+    return LispInteger.getInstance(result);
   }
 
   @Override
@@ -490,10 +466,7 @@
     if (obj instanceof Fixnum)
       {
         long result = (long) value * ((Fixnum)obj).value;
-        if (result >= Integer.MIN_VALUE && result <= Integer.MAX_VALUE)
-          return Fixnum.getInstance((int)result);
-        else
-          return new Bignum(result);
+        return LispInteger.getInstance(result);
       }
     if (obj instanceof Bignum)
       return number(getBigInteger().multiply(((Bignum)obj).value));
@@ -838,10 +811,7 @@
     if (shift <= 32)
       {
         n = n << shift;
-        if (n >= Integer.MIN_VALUE && n <= Integer.MAX_VALUE)
-          return Fixnum.getInstance((int)n);
-        else
-          return new Bignum(n);
+        return LispInteger.getInstance(n);
       }
     // BigInteger.shiftLeft() succumbs to a stack overflow if shift
     // is Integer.MIN_VALUE, so...
@@ -961,7 +931,7 @@
     BigInteger y = Bignum.getValue(obj);
 
     if (y.compareTo (BigInteger.ZERO) < 0)
-      return (Fixnum.getInstance(1)).divideBy(this.pow(new Bignum(y.negate())));
+      return (Fixnum.getInstance(1)).divideBy(this.pow(Bignum.getInstance(y.negate())));
 
     if (y.compareTo(BigInteger.ZERO) == 0)
       // No need to test base here; CLHS says 0^0 == 1.
@@ -987,7 +957,7 @@
       y = y.shiftLeft(1);
     }
 
-    return new Bignum(xy);
+    return Bignum.getInstance(xy);
   }
 
   @Override

Modified: trunk/abcl/src/org/armedbear/lisp/FloatFunctions.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/FloatFunctions.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/FloatFunctions.java	Wed Apr  1 15:58:11 2009
@@ -154,12 +154,12 @@
             if (arg instanceof SingleFloat) {
                 int bits = Float.floatToIntBits(((SingleFloat)arg).value);
                 BigInteger big = BigInteger.valueOf(bits >> 1);
-                return new Bignum(big.shiftLeft(1).add(((bits & 1) == 1) ? BigInteger.ONE : BigInteger.ZERO));
+                return Bignum.getInstance(big.shiftLeft(1).add(((bits & 1) == 1) ? BigInteger.ONE : BigInteger.ZERO));
             }
             if (arg instanceof DoubleFloat) {
                 long bits = Double.doubleToLongBits(((DoubleFloat)arg).value);
                 BigInteger big = BigInteger.valueOf(bits >> 1);
-                return new Bignum(big.shiftLeft(1).add(((bits & 1) == 1) ? BigInteger.ONE : BigInteger.ZERO));
+                return Bignum.getInstance(big.shiftLeft(1).add(((bits & 1) == 1) ? BigInteger.ONE : BigInteger.ZERO));
             }
             return type_error(arg, Symbol.FLOAT);
         }

Modified: trunk/abcl/src/org/armedbear/lisp/JavaObject.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/JavaObject.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/JavaObject.java	Wed Apr  1 15:58:11 2009
@@ -134,7 +134,7 @@
                 return LispInteger.getInstance(((Long)obj).longValue());
 
             if (obj instanceof BigInteger)
-                return new Bignum((BigInteger)obj);
+                return Bignum.getInstance((BigInteger)obj);
 
             if (obj instanceof Short)
                 return Fixnum.getInstance(((Short)obj).shortValue());

Modified: trunk/abcl/src/org/armedbear/lisp/Lisp.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Lisp.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Lisp.java	Wed Apr  1 15:58:11 2009
@@ -881,7 +881,7 @@
     if (n >= Integer.MIN_VALUE && n <= Integer.MAX_VALUE)
       return Fixnum.getInstance((int)n);
     else
-      return new Bignum(n);
+      return Bignum.getInstance(n);
   }
 
   private static final BigInteger INT_MIN = BigInteger.valueOf(Integer.MIN_VALUE);
@@ -915,7 +915,7 @@
     if (n.compareTo(INT_MIN) >= 0 && n.compareTo(INT_MAX) <= 0)
       return Fixnum.getInstance(n.intValue());
     else
-      return new Bignum(n);
+      return Bignum.getInstance(n);
   }
 
   public static final int mod(int number, int divisor)
@@ -1219,7 +1219,7 @@
     list(Symbol.UNSIGNED_BYTE, Fixnum.constants[32]);
 
   public static final LispObject UNSIGNED_BYTE_32_MAX_VALUE =
-    new Bignum(4294967296L);
+    Bignum.getInstance(4294967296L);
 
   public static final LispObject getUpgradedArrayElementType(LispObject type)
     throws ConditionThrowable
@@ -2088,8 +2088,8 @@
   {
     Symbol.MOST_POSITIVE_FIXNUM.initializeConstant(Fixnum.getInstance(Integer.MAX_VALUE));
     Symbol.MOST_NEGATIVE_FIXNUM.initializeConstant(Fixnum.getInstance(Integer.MIN_VALUE));
-    Symbol.MOST_POSITIVE_JAVA_LONG.initializeConstant(new Bignum(Long.MAX_VALUE));
-    Symbol.MOST_NEGATIVE_JAVA_LONG.initializeConstant(new Bignum(Long.MIN_VALUE));
+    Symbol.MOST_POSITIVE_JAVA_LONG.initializeConstant(Bignum.getInstance(Long.MAX_VALUE));
+    Symbol.MOST_NEGATIVE_JAVA_LONG.initializeConstant(Bignum.getInstance(Long.MIN_VALUE));
   }
 
   public static void exit(int status)

Modified: trunk/abcl/src/org/armedbear/lisp/LispInteger.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/LispInteger.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/LispInteger.java	Wed Apr  1 15:58:11 2009
@@ -43,7 +43,7 @@
       if (Integer.MIN_VALUE <= l && l <= Integer.MAX_VALUE)
           return Fixnum.getInstance((int)l);
       else
-          return new Bignum(l);
+          return Bignum.getInstance(l);
   }
 
   public static LispInteger getInstance(int i) {

Modified: trunk/abcl/src/org/armedbear/lisp/RuntimeClass.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/RuntimeClass.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/RuntimeClass.java	Wed Apr  1 15:58:11 2009
@@ -169,9 +169,9 @@
         return Fixnum.getInstance(i);
     }
 
-    public static final Bignum makeLispObject(long i) throws ConditionThrowable
+    public static final LispInteger makeLispObject(long i) throws ConditionThrowable
     {
-        return new Bignum(i);
+        return Bignum.getInstance(i);
     }
 
     public static final SingleFloat makeLispObject(float i) throws ConditionThrowable

Modified: trunk/abcl/src/org/armedbear/lisp/Stream.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Stream.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Stream.java	Wed Apr  1 15:58:11 2009
@@ -1356,7 +1356,7 @@
     // parseInt() failed.
     try
       {
-        return new Bignum(token, radix);
+        return Bignum.getInstance(token, radix);
       }
     catch (NumberFormatException e) {}
     // Not a number.
@@ -1493,7 +1493,7 @@
     // parseInt() failed.
     try
       {
-        return new Bignum(s, radix);
+        return Bignum.getInstance(s, radix);
       }
     catch (NumberFormatException e) {}
     // Not a number.
@@ -1522,7 +1522,7 @@
     // parseInt() failed.
     try
       {
-        return new Bignum(s, radix);
+        return Bignum.getInstance(s, radix);
       }
     catch (NumberFormatException e) {}
     // Not a number.

Modified: trunk/abcl/src/org/armedbear/lisp/compiler-pass2.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/compiler-pass2.lisp	(original)
+++ trunk/abcl/src/org/armedbear/lisp/compiler-pass2.lisp	Wed Apr  1 15:58:11 2009
@@ -2200,21 +2200,20 @@
    (setf g (concatenate 'string "BIGNUM_" (symbol-name (gensym))))
    (let ((*code* *static-code*))
      (declare-field g +lisp-integer+)
-     (emit 'new +lisp-bignum-class+)
-     (emit 'dup)
      (cond ((<= most-negative-java-long n most-positive-java-long)
 ;;	    (setf g (format nil "BIGNUM_~A~D"
 ;;			    (if (minusp n) "MINUS_" "")
 ;;			    (abs n)))
 	    (emit 'ldc2_w (pool-long n))
-	    (emit-invokespecial-init +lisp-bignum-class+ '("J")))
+	    (emit-invokestatic +lisp-bignum-class+ "getInstance"
+                               '("J") +lisp-integer+))
 	 (t
 	  (let* ((*print-base* 10)
 		 (s (with-output-to-string (stream) (dump-form n stream))))
 	    (emit 'ldc (pool-string s))
 	    (emit-push-constant-int 10)
-	    (emit-invokespecial-init +lisp-bignum-class+
-                                     (list +java-string+ "I")))))
+	    (emit-invokestatic +lisp-bignum-class+ "getInstance"
+                               (list +java-string+ "I") +lisp-integer+))))
      (emit 'putstatic *this-class* g +lisp-integer+)
      (setf *static-code* *code*))
    (setf (gethash n ht) g)))




More information about the armedbear-cvs mailing list