Author: Tobias Pape <[email protected]>
Branch: 
Changeset: r22:d0ece51ae683
Date: 2013-01-25 08:07 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/d0ece51ae683/

Log:    fix Large Integers. They can be more than four bytes wide. The ruint
        test passes on 64bit now, too

diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -173,8 +173,10 @@
             except WrappingError:
                 pass
         # XXX this is not really working well on 64 bit machines
-        w_result = 
model.W_BytesObject(self.classtable['w_LargePositiveInteger'], 4)
-        for i in range(4):
+        import math
+        bytes_len = max(4, int(math.log(val, 0xff)) + 1)
+        w_result = 
model.W_BytesObject(self.classtable['w_LargePositiveInteger'], bytes_len)
+        for i in range(bytes_len):
             w_result.setchar(i, chr(intmask((val >> i*8) & 255)))
         return w_result
 
@@ -221,12 +223,10 @@
         if isinstance(w_value, model.W_BytesObject):
             # TODO: Completely untested! This failed translation bigtime...
             # XXX Probably we want to allow all subclasses
-            if not (w_value.getclass(self).is_same_object(
-                self.w_LargePositiveInteger) and
-                w_value.size() == 4):
+            if not 
w_value.getclass(self).is_same_object(self.w_LargePositiveInteger):
                 raise UnwrappingError("Failed to convert bytes to word")
             word = 0 
-            for i in range(4):
+            for i in range(w_value.size()):
                 word += r_uint(ord(w_value.getchar(i))) << 8*i
             return word
         else:
diff --git a/spyvm/test/test_objectspace.py b/spyvm/test/test_objectspace.py
--- a/spyvm/test/test_objectspace.py
+++ b/spyvm/test/test_objectspace.py
@@ -28,25 +28,30 @@
     assert w_Metaclass.w_class.w_class is w_Metaclass
 
 def test_ruint():
+    """
+    | a b |
+    a := (9223372036854775808).
+    b := LargePositiveInteger new: a size + 1.
+    1 to: a size do: [:index |
+        b digitAt: index put: (a digitAt: index)].
+    b digitAt: (a size + 1) put: 1.
+    b.
+    => 27670116110564327424
+    """
+
     from rpython.rlib.rarithmetic import r_uint
-    for num in [0, 1, 41, 100, 2**31]:
+    for num in [0, 1, 41, 100, 2**31, sys.maxint + 1]:
         num = r_uint(num)
         assert space.unwrap_uint(space.wrap_uint(num)) == num
-    for num in [-1, -100]:
-        py.test.raises(objspace.WrappingError, space.wrap_uint, num)
+    for num in [-1, -100, -sys.maxint]:
+        with py.test.raises(objspace.WrappingError):
+            space.wrap_uint(num)
     for obj in [space.wrap_char('a'), space.wrap_int(-1)]:
-        py.test.raises(objspace.UnwrappingError, space.unwrap_uint, obj)
+        with py.test.raises(objspace.UnwrappingError):
+            space.unwrap_uint(obj)
     byteobj = space.wrap_uint(sys.maxint + 1)
     byteobj.bytes.append('\x01')
-    py.test.raises(objspace.UnwrappingError, space.unwrap_uint, byteobj)
+    num = space.unwrap_uint(byteobj)
+    # should not raise. see docstring.
+  
 
[email protected]("sys.maxint > 2147483647")
-def test_ruint_max():
-    from rpython.rlib.rarithmetic import r_uint
-    num = r_uint(sys.maxint + 1)
-    assert space.unwrap_uint(space.wrap_uint(num)) == num
-    num = -sys.maxint
-    py.test.raises(objspace.WrappingError, space.wrap_uint, num)
-
-    
-
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to